Posiblemente una solución simple que perdí. ¿Cómo puedo atq
ordenar el resultado cronológicamente, para poder ver fácilmente quién se ejecutará a continuación? La man
página sort
no 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 |sort
Tampoco funcionaría en el salto de identificación del trabajo.
Respuesta1
Suponiendo que estás en Linux, la salida de atq
siempre 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 atq
se usa.
atq | sort -k 6n -k 3M -k 4n -k 5 -k 7 -k 1
# year month day time queue id
Respuesta2
El sort
comando puede hacerlo, pero desafortunadamente no se puede usar --month-sort
y --numeric-sort
juntos. 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 date
que 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
atq
permite 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 atqq
que
- 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