Kirjoittaja Aihe: Aikaleiman käsittelyn muunnos bashistä dashiin  (Luettu 2538 kertaa)

AimoE

  • Käyttäjä
  • Viestejä: 2714
    • Profiili
Minulla on toimiva scripti, jonka haluan muunta dashin hyvkäsymään muotoon. Siinä on yksi kohta, jota en saa muunnettua. Ongelma koskee sitä, miten date-komentoa käytetään.

Bash-muodossa ongelmakoodi on tämän tapainen (olen tehnyt tästä erillisen komentotiedosto testaamista varten):

Koodia: [Valitse]
fmt_time () {
    days=$(( $1 / (24*20*60) ))
    [ $days -ge 1 ] && printf "$days days, "
    printf $(date -u -d @$1 +%T)
}
lasted () {
    fmt_time $(( $(date -d "$2" +%s) - $(date -d "$1" +%s) ))
}
log='
      Started: 05:39:22 AM 23/06/2021
      Stopped: 05:40:53 AM 23/06/2021
'
sta=( $(sed -n -e 's/^.*Started: //p'<<<$log) )
sto=( $(sed -n -e 's/^.*Stopped: //p'<<<$log) )
echo Lasted $(lasted $sta $sto)

Tämä siis toimii kun sen suorittaa bashillä. Alunperin yritin poimia molemmat aikaleimat samaan array-muuttujaan ja kun erotin ne eri muuttujiin, array jäi käyttöön ihan epähuomiossa. Kun sitten yritin muuntaa tämän dashin hyväksymään muotoon, kävi ilmi että date hyväksyy nämä aikaleimat vain array-tyyppisinä mutta ei merkkijonoina.

Oletin että kolme viimeistä riviä pitäisi kirjoittaa näin:

Koodia: [Valitse]
sta=$(echo "$log" | sed -n -e 's/^.*Started: //p')
sto=$(echo "$log" | sed -n -e 's/^.*Stopped: //p')
echo Lasted $(lasted "$sta" "$sto")

Vaan eipä tämä toimi edes bashissä, kun en tiedä miten nuo aikaleimat pitäisi muuntaa date:a varten.

Löytyykö vinkkiä?

Edit: siistin koodiesimerkkiä (ensimmäinen blokki yllä). Myös siistitty versio on testaamalla toimivaksi todettu.
« Viimeksi muokattu: 23.06.21 - klo:19.54 kirjoittanut AimoE »

SuperOscar

  • Käyttäjä
  • Viestejä: 4000
  • Ocatarinetabellatsumtsum!
    • Profiili
    • Legisign.org
Vs: Aikaleiman käsittelyn muunnos bashistä dashiin
« Vastaus #1 : 23.06.21 - klo:20.29 »
Nähtävästi date olettaa amerikkalaisen järjestyksen kuukausi/päivä/vuosi, ts.  "05:39:22 AM 23/06/2021” aiheuttaa virheen mutta ”05:39:22 AM 06/23/2021” toimii.
pöytäkone 1, kannettavat 1–3: Debian GNU/Linux 12; pöytäkone 2: openSUSE Tumbleweed; NUC: openSUSE Leap 15.5; RPi 1: FreeBSD 13.2-RELEASE; RPi 2: LibreELEC 11

AimoE

  • Käyttäjä
  • Viestejä: 2714
    • Profiili
Vs: Aikaleiman käsittelyn muunnos bashistä dashiin
« Vastaus #2 : 23.06.21 - klo:20.46 »
Nähtävästi date olettaa amerikkalaisen järjestyksen kuukausi/päivä/vuosi, ts.  "05:39:22 AM 23/06/2021” aiheuttaa virheen mutta ”05:39:22 AM 06/23/2021” toimii.

date-komennon ohjeissa kerrotaan että date hyväksyy vaikka mitä muotoja, joten on vaikea uskoa että asia olisi noin yksinkertainen. Komentorivillä annettavat parametrit ovat pohjimmiltaa merkkijonoja, joten kun date hyväksyy arrayn mutta ei merkkijonoa, herää kysymys hyväksyykö date sen vahingossa tms. Täytyy siis opiskella myös bash array tarkemmin.

jarmala

  • Käyttäjä
  • Viestejä: 774
    • Profiili
Vs: Aikaleiman käsittelyn muunnos bashistä dashiin
« Vastaus #3 : 24.06.21 - klo:01.36 »
date-komennon ohjeissa kerrotaan että date hyväksyy vaikka mitä muotoja, joten on vaikea uskoa että asia olisi noin yksinkertainen.

Asiastahan en mitään ymmärrä, mutta kommentoin kuitenkin sen, mitä opin aikoinaan gnuplotin ja Arduinojen käytön yhteydessä: luen Arduinolta datat Python -skriptillä, jossa komensin ajat näin:

Koodia: [Valitse]
from datetime import datetime
aika = datetime.now().strftime('%H:%M:%S-%d/%m/%Y ')

Ja sitten Gnuplotissa väännän ajan helpommin ymmärrettävään muotoon seuraavasti:
Koodia: [Valitse]
set timefmt "%H:%M:%S-%d/%m/%Y"
set xdata time
set format x "%d.%m.%y\n%H.%M.%S"

Ts. aikojen ja päivämäärien esitysmuotoja voi täysin vapaasti muokata ihan sellaiseen muotoon kuin ikinä haluaa. Kiitos siitä, Unix ja Linux.
Ubuntu 18.04 LTS, Gnome Flashback Metacity, Xeon E3-1245 V2, 8 GB
Ubuntu 22.04 LTS, KDE Plasma, Celeron N5105, 8 GB

AimoE

  • Käyttäjä
  • Viestejä: 2714
    • Profiili
Vs: Aikaleiman käsittelyn muunnos bashistä dashiin
« Vastaus #4 : 24.06.21 - klo:09.20 »
Vika oli siinä että rivillä

Koodia: [Valitse]
echo Lasted $(lasted $sta $sto)
viittaan kummankin arrayn ekaan alkioon, jolloin date ei valita, enkä huomaa virhettä jos kumpikin 12-tuntisen kellon aika on samalta 12 tunnin jaksolta.

SuperOscar on oikeassa, päiväyksen muoto täytyy muuntaa datelle sopivaan muotoon.

Gnluplotia en ole koskaan opetellut, enkä oikein tiedä onko sen käyttö mielekästä pelkkään päivämäärämuunnokseen.
« Viimeksi muokattu: 24.06.21 - klo:09.24 kirjoittanut AimoE »

AimoE

  • Käyttäjä
  • Viestejä: 2714
    • Profiili
Vs: Aikaleiman käsittelyn muunnos bashistä dashiin
« Vastaus #5 : 24.06.21 - klo:11.34 »
Täjän päädyin:

Koodia: [Valitse]
secs2range () {
    days=$(( $1 / (24*20*60) ))
    [ $days -ge 1 ] && printf "$days days, "
    printf $(date -u -d @$1 +%T)
}
dates2range () {
    secs2range $(( $(date -d "$2" +%s) - $(date -d "$1" +%s) ))
}
log2date () {
    echo -n "$2" | sed -n -E "s/^.*$1: (.*) (.*)\/(.*)\/(.*)/\1 \4-\3-\2/p"
}
log='
      Started: 05:39:22 AM 23/06/2021
      Stopped: 05:40:53 AM 23/06/2021
'
sta=$(log2date Started "$log")
sto=$(log2date Stopped "$log")
echo $(dates2range "$sta" "$sto")