Jobs chronologisch sortieren

Jobs chronologisch sortieren

Möglicherweise habe ich eine einfache Lösung verlegt. Wie kann ich die Ausgabe atqchronologisch sortieren, damit ich leicht erkennen kann, wer als nächstes an der Reihe ist? Die manSeite für sorthat keine Funktion zum Erkennen von Zeitstempeln wie den folgenden eingebaut:

atq
1264    Sat Mar 24 15:03:00 2012 a master
1445    Sat Mar 24 20:28:00 2012 a master
1548    Sun Mar 25 15:09:00 2012 a master
1193    Sat Mar 24 11:03:00 2012 a master
1359    Sat Mar 24 17:13:00 2012 a master
1726    Mon Mar 26 21:24:00 2012 a master
1736    Mon Mar 26 22:04:00 2012 a master
1748    Mon Mar 26 22:46:00 2012 a master
1704    Mon Mar 26 20:19:00 2012 a master
1288    Sat Mar 24 15:38:00 2012 a master
1532    Sun Mar 25 11:53:00 2012 a master

atq |sortwürde auch beim Herumspringen der Job-IDs nicht funktionieren.

Antwort1

Vorausgesetzt, Sie verwenden Linux, atqhat die Ausgabe das Datum immer im gleichen Format. Sortieren Sie die Felder in der richtigen Reihenfolge und geben Sie an, welche Zahlen oder Monatsnamen sind. Achten Sie darauf, für die Monatsnamen ein englisches Gebietsschema zu verwenden, da dies atqverwendet wird.

atq | sort -k 6n -k 3M -k 4n -k 5 -k 7 -k 1
#          year  month day   time queue id

Antwort2

Der sortBefehl kann dies, aber leider können Sie --month-sortund nicht --numeric-sortzusammen verwenden. Verwenden Sie also:

$ atq |
    sed 's/Jan/1/;s/Feb/2/;s/Mar/3/;s/Apr/4/;s/May/5/;s/Jun/6/;s/Jul/7/;s/Aug/8/;s/Sep/9/;s/Oct/10/;s/Nov/11/;s/Dec/12/' |
    sort -n -k6,6 -k3,4

Dadurch werden die Monatsabkürzungen in ihre numerischen Werte umgewandelt und dann zuerst nach Jahr ( -k6,6), dann nach Monat und Tag ( -k3,4) sortiert. Die Ausgabe enthält nicht die Monatsnamen, aber wenn Sie diese wirklich möchten, können Sie sie mit einem anderen wieder zurückkonvertieren sed.

$ atq |
    sed 's/Jan/1/;s/Feb/2/;s/Mar/3/;s/Apr/4/;s/May/5/;s/Jun/6/;s/Jul/7/;s/Aug/8/;s/Sep/9/;s/Oct/10/;s/Nov/11/;s/Dec/12/' |
    sort -n -k6,6 -k3,4 |
    sed 'h;s/^[0-9][0-9]*  *[A-Z][a-z][a-z] *\([0-9][0-9]*\).*/\1/;s/10/Oct/;s/11/Nov/;s/12/Dec/;s/1/Jan/;s/2/Feb/;s/3/Mar/;s/4/Apr/;s/5/May/;s/6/Jun/;s/7/Jul/;s/8/Aug/;s/9/Sep/;G;s/^\(.*\)\n\([0-9][0-9]*  *[A-Z][a-z][a-z] *\)[0-9][0-9]*\( .*\)/\2\1\3/'

Beachten Sie, dass dies s/12/Dec/vor kommen muss s/1/Jan/.

Antwort3

Sieht kompliziert aus, funktioniert aber auch so:

atq |awk '{system("echo "$1 "  $(date +%Y-%m-%d_%H-%M-%S \
--date \""$2" "$3" "$4" "$5" "$6"\")  "$7"  "$8 )}' |sort -k2 
    469  2012-03-24_01-30-00  a  master
    655  2012-03-24_02-03-00  a  master
    671  2012-03-24_02-04-00  a  master
    657  2012-03-24_02-09-00  a  master
    673  2012-03-24_02-11-00  a  master
    537  2012-03-25_00-38-00  a  master
    539  2012-03-25_00-43-00  a  master
    652  2012-03-27_12-57-00  a  master
    654  2012-03-27_13-03-00  a  master
    656  2012-03-27_13-09-00  a  master

Im Vergleich zu anderen Vorschlägen gefällt mir, dass die eigentliche Analyse demjenigen überlassen wird, der dateden Textzeitstempel versteht. So können Sie ihn nach Belieben neu formatieren, was das spätere Filtern oder Sortieren zu einem Kinderspiel macht.

|column -t Sie können am Ende ein anheften , um die Felder sauber auszurichten und zu verteilen.

Antwort4

atqerlaubt es, ein »strftime-ähnliches Zeitformat« zu definieren. Man kann die Epoche zum einfachen Sortieren verwenden und das später in etwas Lesbares umwandeln. Die Epoche hat außerdem den Vorteil, dass man Zeitberechnungen durchführen kann.

$ atq -o%s | sort -k2n | while read -r id epoch data; do
    echo "$id $(date --date @$epoch) $data"
done

Ich verwende diese Methode in einem Skript, atqqdas

  • sortiert Jobs nach Datum,
  • druckt den Jobbefehl aus und
  • zeigt die Dauer bis zum Fälligkeitsdatum des Ereignisses an.

Beispielausgabe:

$ atqq
5515 2023-11-02 12:00:00 a user: "strobe blue" (1:59:08)
5514 2023-11-02 12:30:00 a user: "strobe red" (2:29:08)
#!/bin/bash

duration() {
        local i=$1
        local d=$((i / (3600 * 24)))
        ((i %= 3600 * 24))
        local h=$((i / 3600))
        ((i %= 3600))
        local m=$((i / 60))
        local s=$((i % 60))

        if [ $d -gt 0 ]; then
                printf "%ud %u:%02u:%02u" $d $h $m $s
        elif [ $h -gt 0 ]; then
                printf "%u:%02u:%02u" $h $m $s
        elif [ $m -gt 0 ]; then
                printf "%u:%02u" $m $s
        else
                printf "%u" $s
        fi
}

now=$(date +%s)

atq -o%s | sort -k2n | while read -r id epoch data; do
        date=$(date --date @$epoch +%F\ %T)
        cmd=$(at -c $id | sed '/^$/d' | tail -1)
        diff=$((epoch - now))
        if [ $diff -gt 0 ]; then
                remaining="\e[32m$(duration $diff)\e[m"
        else
                remaining="\e[31m-$(duration ${diff#-})\e[m"
        fi

        echo -e "\e[1m$id\e[m $date $data: \e[33m\"$cmd\"\e[m ($remaining)"
done

verwandte Informationen