Ordenar la salida de find -exec ls

14

¿Es posible la salida de orden find … -exec ls -ls ;alfabético, por nombre de archivo?

Este es mi comando cron:

find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;

Este comando funciona bien, en su mayor parte. Pero los resultados no están ordenados en ninguna secuencia significativa. Sería muy útil si se ordenaran por el campo de nombre de archivo.

Comandante
fuente
1
Usando zsh? ls -ls **/*(.)
Kevin
@ Kevin No del todo, lsordenaría.
Gilles 'SO- deja de ser malvado'

Respuestas:

14

Supongo que sus nombres de archivo no contienen nuevas líneas.

find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10

Usar en +lugar de ;terminar la -execacción lo hace más rápido al agrupar las invocaciones de ls. Puede ordenar por canalización a través del sortcomando; dígale que comience a ordenar en el décimo campo (los primeros 9 son los metadatos: bloques, permisos, recuento de enlaces, usuario, grupo, tamaño y 3 campos de fecha / hora). La opción -nle indica lsque use valores numéricos para el usuario y el grupo, lo que evita el riesgo de que los nombres de usuarios o grupos contengan espacios en blanco.

Alternativamente, con zsh, puede escapar sin suponer ningún nombre utilizando calificadores globales para recopilar y ordenar los archivos y zargsejecutarlos lsvarias veces si la línea de comando es demasiado larga. Necesitas GNU ls(específicamente su -fopción) para evitar reordenar por ls(otro enfoque sería emular lscon zsh zstat).

autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf
Gilles 'SO- deja de ser malvado'
fuente
Muchas gracias! Usar el primer comando que enviaste hace la ordenación. ¿Seguiría siendo el número 10 si uso una ruta más corta? Por ejemplo, si ejecuto el mismo comando desde / home / setefgge en lugar de desde public_html?
MaJ
@MaJ 10 es el número de campos omitidos, no tiene nada que ver con el tamaño del nombre del archivo.
Gilles 'SO- deja de ser malvado'
Gracias. Agradezco su ayuda, y también la ayuda que todos los demás brindaron. Considero este problema resuelto. Mi comando cron ahora está ordenando los archivos. Esta es la primera vez que envío una pregunta a Stackexchange. No veo una opción "Resuelta". Si alguno de ustedes sabe cómo publicar esto como resuelto, continúe y hágalo. ¡Gracias!
MaJ
@MaJ Lo más parecido a marcar una pregunta como resuelta es marcar una de las respuestas como aceptada. Solo usted, el autor de la pregunta, puede hacerlo. Para hacer esto, haga clic en la marca de verificación junto a la respuesta que más le ayudó. Si aceptas una respuesta, obtendrás 2 puntos de reputación más, y después podrás votar en las publicaciones; puedes votar todas las publicaciones que te resultaron útiles. Para obtener más información, consulte la página del recorrido y la página de ayuda sobre qué hacer cuando alguien responde a su pregunta .
Gilles 'SO- deja de ser malvado'
1

¿Por qué no canalizar el resultado de find through sort y luego ejecutar ls para cada una de las líneas?

find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done
groxxda
fuente
1

POSIX tiene esto que decir sobre las fechas en un ls -llistado único:

El <date and time>campo deberá contener la fecha y la hora apropiadas de cuándo se modificó el archivo por última vez. En el entorno local POSIX, el campo será el equivalente de la salida del siguiente comando de fecha:

date "+%b %e %H:%M"

... si el archivo ha sido modificado en los últimos seis meses, o:

date "+%b %e %Y"

Teniendo esto en cuenta, y asegurándose de que si hay líneas nuevas en un nombre de archivo que estén correctamente bloqueadas con la ls -qopción también especificada POSIX , es relativamente fácil preparar una expresión regular para un lsresultado sin findnada:

d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"

###OUTPUT###
Jul  5 Jul  4

greppara eso y solo devolverá líneas que contienen las cadenas que representan las fechas de hoy o de ayer. El siguiente comando se suma a eso un poco:

ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

ls las opciones consisten en:

  1. -a devolver todos los archivos en un directorio, incluidos los que comienzan con un .dot
  2. -l listado largo
  3. -R enumerar recursivamente todos los directorios secundarios
  4. -c mostrar el tiempo de modificación en lugar del tiempo de acceso
  5. -qdevolver el globo de shell en ?lugar de caracteres no imprimibles o \tab en un nombre de archivo

Esos resultados se pasan sobre el |pipearchivo al sedque solo coincide:

  1. La línea en blanco que precede a un nombre de ruta y la siguiente línea
  2. Líneas que comienzan con - (en otras palabras, no dpara el directorio) que también contienen su date.
  3. Sin embargo, no imprime las líneas del nombre de ruta a menos que el directorio que nombre contenga realmente los archivos por los que ha filtrado.

El resultado se ve así:

ls -alRcq --color=always | 
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv   2086 Jul  4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv   2657 Jul  4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv    681 Jul  5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul  5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul  4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul  4 13:34 shot-2014-06-22_17-11-06.jpg

./.cache/efreet:
-rw------- 1 mikeserv mikeserv  37325 Jul  4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv  37325 Jul  4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  16037 Jul  4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv   3117 Jul  4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul  4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv  18589 Jul  4 23:30 icons_hicolor_localhost.eet

./.config:
-rw-r--r-- 1 mikeserv mikeserv   30 Jul  4 19:10 pavucontrol.ini

./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul  4 13:36 conf.tar.lz4.bak

Sí, incluso funciona LS_COLORS, lo que probablemente es una prioridad baja para usted, cronpor supuesto, pero, hey, sus opciones están abiertas.

En cualquier caso, esto ofrece algunas ventajas significativas sobre otras posibles soluciones.

  1. En primer lugar, find+ lsimplica múltiples invocaciones: esto solo implica un único lsproceso, y es por eso que es capaz de clasificar todo de manera confiable, lo que hace de manera predeterminada, y sorttambién se hace auxiliar.

  2. Cualquier solución que involucre findy sortya lsestá haciendo casi todo el trabajo dos veces. lsy findambos resolverán cada ruta y statcada archivo. lsy sortambos ordenarán todos los resultados. Probablemente sea mejor usar el sencillo ls.

  3. Luego, por supuesto, están las partes datey sedde esta respuesta. Lo importante a tener en cuenta al respecto es que haces la parte difícil y obtienes la expresión regular primero, y solo una vez, y luego solo podas una lista de resultados en lugar de decir, obtener resultados, obtener resultados, ordenar resultados y ordenar resultados.

  4. Esto no se rompe en los nombres de archivo que contienen nuevas líneas, como probablemente lo harán otras soluciones. Esta solución tiene sus propias advertencias, que explico a continuación, pero son minuciosas y fáciles de manejar. En mi opinión, esta es la solución más sólida aquí.

Hay dos casos en los que el comando anterior puede causarle problemas. El primero involucra los ?globos en los nombres de archivo, mientras que ya es una solución más sólida que cualquier otra que se ofrezca aquí, y la probabilidad de que encuentres una ?es bastante pequeña por sí sola, existe la posibilidad de resolver esos globos. podría coincidir con más de un nombre de archivo. Consulte esto para obtener más información sobre este tema.

La otra posibilidad implica un falso positivo, por ejemplo, si tiene un nombre de archivo que realmente coincide con la datecadena que estamos buscando greppero que en realidad no se modificó en ninguno de esos días. No cuento con que eso sea un problema, pero, si lo es, pregunte al respecto y probablemente pueda ayudarlo a hacer que la expresión regular sea más específica para manejar esto.

mikeserv
fuente
0

En realidad, puede usar una combinación de find, xargs y ls.

Aquí hay un comando de muestra: find . -type f -print0 | xargs -0 ls -lt

  • find buscará recursivamente todos los archivos en el directorio actual.
  • xargs pasará esta lista de archivos al lscomando en una sola llamada (siempre finddevuelve menos que los ARG_MAXarchivos).
  • ls -lt ordenará estos archivos por hora y formateará la salida

Para recuperar su sistema ARG_MAX, puede escribir:

$ getconf ARG_MAX
> 2621440
Max
fuente
-1
ls -l $(find /home/setefgge/public_html -type f -ctime -1 | sort)
Walter A
fuente
1
lshace su propia clasificación, por lo que canalizar la salida de findthrough sortes inútil. Además, su comando manipula los nombres de archivo que contienen espacios en blanco (entre otros) y fallará si hay demasiados nombres de archivo.
Gilles 'SO- deja de ser malvado'