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 @xxxxxxy 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 GNUparalleloxargs²: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
sortsi es necesario:¹ Esto supone que no hay subdirectorios anidados, como parece ser el caso de su ejemplo. También se puede utilizar
./ -mindepth 1en lugar de*² Se puede reemplazar
parallelconxargs -I{}aquí como @hobbs y @don_crissti sugerido, simplemente más prolija. ³ basado en la respuesta de Gilles para usardatelas capacidades de lectura de archivosfuente
xargssi no tienesparallel, lo que probablemente muchas personas no tienen.xargsno tiene la opción de especificar dónde va el argumento como lo hizoparallelcon{}.find ./ -type d | cut -c 3-12 | xargs -I{} date --d @{} +'%Y-%m-%d'-Iopción.--do--dafuncionaría con versiones actuales de GNUdate, pero podría dejar de funcionar el día quedateintroduce una--dalekopció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
finden la subshell y mantiene el bucle while en el shell principal. Que la sintaxis (AT & Tksh,zshybashespecí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
datela 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 segundasededició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,
strftimepor ejemplo:Para convertir esto en un revestimiento en tu tubería:
Pero probablemente sugeriría en cambio mirar el uso del
File::Findmó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
zshy 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
parallelestá escrito enperl. Esto parece excesivo teniendo enperlcuenta que tiene unstrftime()operador. Me gustaperl -MPOSIX -lpe '$_.=strftime(" %c", localtime substr $_, 2, 10)'parallel. IMO,paralleles 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
execargumentos.En su caso, puede hacer lo siguiente:
fuente
Usando Python (es la solución más lenta)
da:
fuente