ordenar los trabajos cronológicamente

ordenar los trabajos cronológicamente

Posiblemente una solución simple que perdí. ¿Cómo puedo atqordenar el resultado cronológicamente, para poder ver fácilmente quién se ejecutará a continuación? La manpágina sortno tiene nada integrado para reconocer marcas de tiempo como las siguientes:

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 |sortTampoco funcionaría en el salto de identificación del trabajo.

Respuesta1

Suponiendo que estás en Linux, la salida de atqsiempre tiene la fecha en el mismo formato. Ordene los campos en el orden apropiado, teniendo cuidado de declarar cuáles son números o nombres de meses. Asegúrese de usar una configuración regional en inglés para los nombres de los meses, ya que eso es lo que atqse usa.

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

Respuesta2

El sortcomando puede hacerlo, pero desafortunadamente no se puede usar --month-sorty --numeric-sortjuntos. Entonces usa:

$ 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

Esto convertirá las abreviaturas de los meses a sus valores numéricos, luego ordenará primero por año ( -k6,6), luego por mes y día ( -k3,4). La salida no tendrá los nombres de los meses, pero si realmente lo desea, puede volver a convertirlos con otro archivo 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/'

Note que esto s/12/Dec/debe venir antes s/1/Jan/.

Respuesta3

Parece complicado pero esto también funciona:

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

En comparación con otras sugerencias, me gusta cómo se deja el análisis real dateque comprende la marca de tiempo textual, por lo que puede reformatear el formato que desee para que sea muy sencillo filtrar u ordenar más tarde.

Puedes agregar un |column -t al final para alinear y espaciar bien los campos.

Respuesta4

atqpermite definir un »formato de hora similar a strftime«. Se puede usar la época para ordenar fácilmente y luego convertirla en algo legible. La época también tiene la ventaja de que se pueden hacer cálculos de tiempo.

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

Utilizo este método en un script atqqque

  • ordena trabajos por fecha,
  • imprime el comando de trabajo y
  • muestra la duración hasta que vence el evento.

Salida de ejemplo:

$ 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

información relacionada