Estoy escribiendo una función que genera fechas. Me gustaría permitir que el usuario personalice la salida proporcionando argumentos date
con una variable de entorno. Para preservar los espacios en blanco en las cadenas de formato, me gustaría aceptar argumentos en una matriz como esta:
function argdates {
while [ $# -gt 0 ] && date "${DATE_ARGS[@]}" -d @$1
do shift
done
}
Es posible que el usuario desee utilizar una matriz si tiene espacios en una cadena con formato de fecha:
DATE_ARGS=( -u "+%y/%U, %I%p %a" )
argdates 1476395008 1493172224
# output:
# 16/41, 09PM Thu
# 17/17, 02AM Wed
Pero en este caso, una matriz podría ser excesiva:
DATE_ARGS="-u -Iseconds"
argdates 1476395008 1493172224
# output:
# date: invalid option -- ' '
# Try 'date --help' for more information.
# output should be:
# 2016-10-13T21:43:28+00:00
# 2017-04-26T02:03:44+00:00
No quiero requerir una matriz para casos simples como este. ¿Es posible saber de qué tipo es la variable?
Respuesta1
Me parece que es posible que desee permitir que su función pase cualquier opción de línea de comando directamente a GNU date
mientras trata especialmente las no opciones numéricas:
argdates () {
local -a opts
local timestamp
while [ "$#" -gt 0 ] && [ "$1" != '--' ] && [[ "$1" != [0-9]* ]]; do
opts+=( "$1" )
shift
done
[ "$1" = '--' ] && shift
for timestamp do
date "${opts[@]}" -d "@$timestamp"
done
# or, with a single invocation of "date":
# printf '@%s\n' "$@" | date "${opts[@]}" -f -
}
Esta bash
función revisaría sus argumentos de línea de comando y los guardaría en la opts
matriz, hasta que encuentre un argumento que sea --
(la forma estándar de señalar el final de las opciones) o que comience con un dígito. Cada argumento guardado en opts
se elimina de la lista de argumentos de la línea de comando.
Una vez que se ha encontrado un argumento que no es una opción date
, asumimos que el resto de los argumentos son marcas de tiempo de época UNIX y los repasamos, llamando date
con nuestras opciones guardadas para cada marca de tiempo. Consulte el comentario en el código sobre cómo realizar este bucle de manera más eficiente.
Invocaciones de ejemplo:
$ argdates 1476395008 1493172224
Thu Oct 13 23:43:28 CEST 2016
Wed Apr 26 04:03:44 CEST 2017
$ argdates -- 1476395008 1493172224
Thu Oct 13 23:43:28 CEST 2016
Wed Apr 26 04:03:44 CEST 2017
$ argdates +%D 1476395008 1493172224
10/13/16
04/26/17
$ argdates +%F 1476395008 1493172224
2016-10-13
2017-04-26
$ argdates -u 1476395008 1493172224
Thu Oct 13 21:43:28 UTC 2016
Wed Apr 26 02:03:44 UTC 2017
$ argdates -u -Iseconds 1476395008 1493172224
2016-10-13T21:43:28+00:00
2017-04-26T02:03:44+00:00
Respuesta2
Podría hacerlo mucho más fácilmente renunciando al uso de matrices y permitiendo que el usuario especifique DATE_ARGS
simplemente como una cadena que debe insertarse en la línea de comando de date
:
$ argdates(){
for d; do printf %s "$DATE_ARGS" | xargs date -d "@$d"; done
}
$ DATE_ARGS='-u "+%y/%U, %I%p %a"' argdates 1476395008 1493172224
16/41, 09PM Thu
17/17, 02AM Wed
$ DATE_ARGS='-u -Iseconds' argdates 1476395008 1493172224
2016-10-13T21:43:28+00:00
2017-04-26T02:03:44+00:00