Tengo directorios cuyos nombres son marcas de tiempo, dadas en milisegundos desde 1970-01-01:
1439715011728
1439793321429
1439879712214
.
.
Y necesito una salida como:
1442039711 Sat Sep 12 08:35:11 CEST 2015
1442134211 Sun Sep 13 10:50:11 CEST 2015
1442212521 Mon Sep 14 08:35:21 CEST 2015
.
.
Puedo enumerar todos los directorios por comando:
find ./ -type d | cut -c 3-12
Pero no puedo poner la salida al siguiente comando: date -d @xxxxxx
y manipular la salida.
¿Cómo puedo hacer esto?
Fri Oct 2 05:35:28 47592
)Respuestas:
Está en el camino correcto (para una solución más simple, ejecutando solo 2 o 3 comandos, consulte a continuación). Debería usar en
*
lugar de./
deshacerse del directorio actual¹ y esto simplifica un poco el corte de los milisegundos, luego simplemente canalice el resultado en GNUparallel
oxargs
²:Llegar
y para agregar los segundos de desplazamiento antes de eso, como indica su ejemplo:
o:
Llegar:
Sin embargo, es más simple hacer³:
lo que te da el mismo resultado solicitado una vez más.
La desventaja de usar
*
es que está limitado por su línea de comandos para su expansión, sin embargo, la ventaja es que ordena sus directorios por valor de marca de tiempo. Si el número de directorios es un problema-mindepth 1
, use , pero pierda el orden:e inserte
sort
si es necesario:¹ Esto supone que no hay subdirectorios anidados, como parece ser el caso de su ejemplo. También se puede utilizar
./ -mindepth 1
en lugar de*
² Se puede reemplazar
parallel
conxargs -I{}
aquí como @hobbs y @don_crissti sugerido, simplemente más prolija. ³ basado en la respuesta de Gilles para usardate
las capacidades de lectura de archivosfuente
xargs
si no tienesparallel
, lo que probablemente muchas personas no tienen.xargs
no tiene la opción de especificar dónde va el argumento como lo hizoparallel
con{}
.find ./ -type d | cut -c 3-12 | xargs -I{} date --d @{} +'%Y-%m-%d'
-I
opción.--d
o--da
funcionaría con versiones actuales de GNUdate
, pero podría dejar de funcionar el día quedate
introduce una--dalek
opción (para fechas en el calendario Dalek).Evitaría ejecutar varios comandos por archivo en un bucle. Como ya estás usando GNUisms:
Que solo ejecuta dos comandos.
strftime()
es específico de GNU, comodate -d
.fuente
Tu ya lo tienes:
que presumiblemente le proporciona las marcas de tiempo en formato de época. Ahora agregue un ciclo while:
Sin embargo, tenga en cuenta que en algunos shells, esa sintaxis obtiene el bucle while en una subshell, lo que significa que si intenta establecer una variable allí, no será visible una vez que haya dejado el bucle. Para solucionarlo, debes cambiar un poco las cosas:
que pone el
find
en la subshell y mantiene el bucle while en el shell principal. Que la sintaxis (AT & Tksh
,zsh
ybash
específico) sólo es necesario si usted está mirando para reutilizar resultado desde el interior del bucle, sin embargo.fuente
done <(find)
lugar dedone < <(find)
, era correcto parayash
(dónde<(...)
está la redirección del proceso, no la sustitución del proceso), por lo que mi edición fue un poco arrogante, ya que podría haber sido el caparazón para el que quiso decir eso.Si tiene una fecha GNU, puede convertir fechas leídas de un archivo de entrada. Solo necesita masajear las marcas de tiempo un poco para que pueda reconocerlas. La sintaxis de entrada para una marca de tiempo basada en la época de Unix es
@
seguida por el número de segundos, que puede contener un punto decimal.fuente
date
la lectura de archivos s. Esto dará undate: invalid date ‘@’
debido a la traducción del directorio actual (./
). Y dado que puede tirar los milisegundos, puede simplificar la segundased
edición para soltar los últimos 3 caracteres. O elimine todo eso y usefind * -type d -printf "@%.10f" | date ...
Lo haría con dulzura: alimentar en una lista de marcas de tiempo:
Esto produce:
Si desea un formato de salida específico, puede usar,
strftime
por ejemplo:Para convertir esto en un revestimiento en tu tubería:
Pero probablemente sugeriría en cambio mirar el uso del
File::Find
módulo y hacer todo en perl. Si da un ejemplo de la estructura de su directorio antes de cortarlo, le daré un ejemplo. Pero sería algo como:fuente
Con
zsh
y el strftime incorporado:Esto supone que todos los nombres de directorio en el directorio actual son en realidad tiempos de época.
Es posible un mayor filtrado / procesamiento siempre que aclare cómo deben procesarse esos números en su ejemplo (se parecen más a los tiempos de época correspondientes a las fechas de nacimiento de la princesa Leia y Luke Skywalker ...) por ejemplo, busque de forma recursiva nombres de directorio que coincidan al menos 10 dígitos y calcule la fecha en función de los primeros 10 dígitos:
fuente
Usando GNU Paralelo:
Si puede aceptar \ t en lugar de espacio:
fuente
parallel
está escrito enperl
. Esto parece excesivo teniendo enperl
cuenta que tiene unstrftime()
operador. Me gustaperl -MPOSIX -lpe '$_.=strftime(" %c", localtime substr $_, 2, 10)'
parallel
. IMO,parallel
es una gran herramienta para paralelizar tareas intensivas de CPU, pero no es realmente apropiado para este tipo de tareas aquí.Normalmente, el comando find se puede encadenar con cualquier comando usando
exec
argumentos.En su caso, puede hacer lo siguiente:
fuente
Usando Python (es la solución más lenta)
da:
fuente