Comandos de tubería después de un xargs canalizado


38

HP-UX ***** B.11.23 U ia64 **** licencia de usuario ilimitada

find . -type d -name *log* | xargs ls -la

me da los nombres de directorio (los que contienen logen el nombre del directorio) seguidos de todos los archivos dentro de ese directorio.

Los directorios  /var/opt/SID/application_a/log/,  /var/opt/SID/application_b/log/,  /var/opt/SID/application_c/log/y así sucesivamente contienen archivos de registro.

Solo quiero que el comando enumere los dos últimos archivos de registro ls, que generalmente encuentro usando ls -latr | tail -2.

La salida tiene que ser algo como esto ...

/var/opt/SID/application_a/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2

find . -type d -name *log* | xargs ls -la | tail -2No me da el resultado anterior. Lo que obtengo es una lista de los últimos dos archivos de find . -type d -name *log* | xargs ls -lacomando.

Entonces, ¿puedo canalizar comandos después de un canalizado xargs? ¿De qué otra manera puedo consultar para obtener la lista de archivos resultante en el formato anterior?

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

me da una lista de diez nombres de directorio dentro del directorio actual que resulta ser /var/opt/SIDy que tampoco es lo que quiero.


2
Debe citar lo *log*contrario, el shell lo expandirá.
Anthon

Tenga en cuenta que sh -cespera el nombre del comando (parámetro 0) como su segundo argumento, por lo que siempre debe hacerlo find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail(observe lstailal final, que servirá como $0para el shell creado). De lo contrario, el primero de sus resultados ocupará ese rol y no se utilizará.
Jonas

Respuestas:


58

Ya casi has llegado. En su último comando, puede usar -Ipara hacer lo lscorrecto

-I replace-str

    Reemplace las ocurrencias de replace-str en los argumentos iniciales con nombres leídos de la entrada estándar. Además, los espacios en blanco sin comillas no terminan los elementos de entrada; en cambio, el separador es el carácter de nueva línea. Implica -xy -L 1.

Entonces, con

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

usted buscará echoel directorio encontrado findy luego lo hará ls | tailen él.


encontrar . -type d -name " log " | xargs -I {} sh -c "echo {}; ls -ltr {} | grep -E \" file_in | file_out \ "| tail -5" Usé este.
persona1

3
Lo hago conxargs -n 1 sh -c 'echo $0'
Ginhing

1
en macOS, el reemplazo no funcionó dentro del comando citado, por lo que echo $0fue útil (y más comprensible)
mpuncel

1
Para hacer que funcione con los nombres de archivo con espacios, el uso -print0, xargs -0y escapar {}entre comillas dobles dentro del shcomando:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
Benedikt Köppel

Yo uso "xargs -n 1 sh -c" echo \ $ 0 | $ func "` si necesito usar la variable $ func
dios


2

Solo además de fredtantini y como aclaración general (ya que los documentos son un poco confusos):

El xargs -I {}tomará las '{}' caracteres de la entrada estándar y reemplazarlos con lo que viene desde la tubería. Esto significa que en realidad podría reemplazar {}con cualquier combinación de caracteres (tal vez para adaptar mejor su sabor de programación preferido). Por ejemplo : xargs -I % sh -c "echo %". Si siempre usa el xargs -I {}puede reemplazarlo xargs -iya que es la taquigrafía.

Luego sh -cle indicará a su bash / shell que lea el siguiente comando desde una cadena y no desde la entrada estándar. Entonces escribir sh -c "echo something"es equivalente a echo something.

El xargs -I {} sh -c "echo {}"leerá la entrada que creó con la sh -cque está echo {}. Como le dijo que reemplazara {}con los argumentos que obtuvo de la tubería, eso es lo que sucederá.

Puede probar esto fácilmente incluso sin tuberías, simplemente escriba el comando anterior en un terminal. Lo que escriba a continuación se enviará a la terminal (Ctrl-D para salir).

En el ls -la {}comando vuelve a ocurrir lo mismo. El {}se reemplaza con el contenido del comando pre-pipe.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.