¿Cómo se pueden comparar dos fechas en un shell?
Aquí hay un ejemplo de cómo me gustaría usar esto, aunque no funciona como está:
todate=2013-07-18
cond=2013-07-15
if [ $todate -ge $cond ];
then
break
fi
¿Cómo puedo lograr el resultado deseado?
shell-script
shell
date
Abdul
fuente
fuente
Respuestas:
Todavía falta la respuesta correcta:
Tenga en cuenta que esto requiere la fecha GNU. La
date
sintaxis equivalente para BSDdate
(como se encuentra en OSX por defecto) esdate -j -f "%F" 2014-08-19 +"%s"
fuente
timeout=$(`date +%Y%m%d%H%M%S` + 500)
) obviamente es incorrecta.date -d 2013-07-18 +%s%N
Te falta el formato de fecha para la comparación:
También te faltan estructuras en bucle, ¿cómo planeas obtener más fechas?
fuente
date
enviado con macOS.date -d
no es estándar y no funciona en un UNIX típico. En BSD incluso intenta establecer el valor de kenelDST
.Puede usar una comparación de cadenas estándar para comparar el orden cronológico [de cadenas en un formato de año, mes y día].
Afortunadamente, cuando [las cadenas que usan el formato AAAA-MM-DD] se ordenan * en orden alfabético, también se ordenan * en orden cronológico.
(* - ordenado o comparado)
No se necesita nada lujoso en este caso. ¡Hurra!
fuente
if [ $(sed -e s/-//g <<< $todate) -ge $(sed -e s/-//g <<< $cond) ];
... Este formato de fecha fue diseñado para ser ordenado usando un orden alfanumérico estándar, o para-
ser despojado y ordenado numéricamente.Este no es un problema de estructuras en bucle sino de tipos de datos.
Esas fechas (
todate
ycond
) son cadenas, no números, por lo que no puede usar el operador "-ge" detest
. (Recuerde que la notación de corchetes es equivalente al comandotest
).Lo que puede hacer es usar una notación diferente para sus fechas para que sean enteros. Por ejemplo:
producirá un número entero como 20130715 para el 15 de julio de 2013. Luego puede comparar sus fechas con "-ge" y operadores equivalentes.
Actualización: si se proporcionan sus fechas (por ejemplo, si las está leyendo desde un archivo en formato 2013-07-13), puede procesarlas fácilmente con tr.
fuente
El operador
-ge
solo funciona con números enteros, que no son sus fechas.Si su script es un script bash o ksh o zsh, puede usar el
<
operador en su lugar. Este operador no está disponible en tablero u otros shells que no van mucho más allá del estándar POSIX.En cualquier shell, puede convertir las cadenas en números respetando el orden de las fechas simplemente eliminando los guiones.
Alternativamente, puede ir tradicional y usar la
expr
utilidad.Como invocar subprocesos en un bucle puede ser lento, puede preferir hacer la transformación utilizando construcciones de procesamiento de cadenas de shell.
Por supuesto, si puede recuperar las fechas sin los guiones en primer lugar, podrá compararlos con
-ge
.fuente
Convierto las cadenas en marcas de tiempo unix (segundos desde 1.1.1970 0: 0: 0). Estos pueden compararse fácilmente
fuente
date
que viene con macOS.También existe este método del artículo titulado: Calculo simple de fecha y hora en BASH de unix.com.
¡Estas funciones son un extracto de un script en ese hilo!
Uso
fuente
date
que viene con macOS.date
agdate
.respuesta específica bash
Como me gusta reducir los tenedores y bash permiten muchos trucos, ahí está mi propósito:
Bien ahora:
Esto volverá a llenar ambas variables
$todate
y$cond
, usando solo una bifurcación, con una salidadate -f -
que toma el estándar para leer una fecha por línea.Finalmente, podrías romper tu ciclo con
O como una función :
Uso de bash 's incorporado
printf
que podría representar la fecha y hora con segundos de época (verman bash
;-)Este script solo usa una bifurcación.
Alternativa con horquillas limitadas y función de lector de fecha
Esto creará un subproceso dedicado (solo una bifurcación):
Como la entrada y la salida están abiertas, se puede eliminar la entrada de fifo.
La función:
Nota Para evitar tenedores inútiles como
todate=$(myDate 2013-07-18)
, la variable debe ser establecida por la función misma. Y para permitir la sintaxis libre (con o sin comillas para la cadena de fechas), el nombre de la variable debe ser el último argumento.Entonces la fecha de comparación:
puede representar:
si fuera de un bucle
O use la función bash de conector de shell:
o
(Que no son exactamente iguales:
.sh
contienen un script de prueba completo si no se obtiene)fuente
date -f -
podría reducir el requisito de recursos.las fechas son cadenas, no enteros; no puede compararlos con operadores aritméticos estándar.
Un enfoque que puede utilizar, si se garantiza que el separador sea
-
:Esto funciona tan atrás como
bash 2.05b.0(1)-release
.fuente
También puede usar la función incorporada de mysql para comparar las fechas. Da el resultado en 'días'.
Simplemente inserte los valores
$DBUSER
y$DBPASSWORD
variables de acuerdo con los suyos.fuente
FWIW: en Mac, parece que alimentar solo una fecha como "2017-05-05" agregará la hora actual a la fecha y obtendrá un valor diferente cada vez que la convierta en tiempo de época. para obtener un tiempo de época más consistente para fechas fijas, incluya valores ficticios para horas, minutos y segundos:
Esto puede ser una rareza limitada a la versión de fecha que se envió con macOS ... probado en macOS 10.12.6.
fuente
Haciendo eco de la respuesta @Gilles ("El operador -ge solo funciona con enteros"), aquí hay un ejemplo.
datetime
conversiones enteras aepoch
, según la respuesta de @ mike-q en https://stackoverflow.com/questions/10990949/convert-date-time-string-to-epoch-in-bash :"$curr_date"
es mayor que (más reciente que)"$old_date"
, pero esta expresión se evalúa incorrectamente comoFalse
:... se muestra explícitamente aquí:
Comparaciones enteras:
fuente
La razón por la que esta comparación no funciona bien con una cadena de fecha con guiones es que el shell supone que un número con un 0 inicial es un octal, en este caso el mes "07". Se han propuesto varias soluciones, pero la más rápida y fácil es eliminar los guiones. Bash tiene una función de sustitución de cadenas que hace que esto sea rápido y fácil, luego la comparación se puede realizar como una expresión aritmética:
fuente