bash find xargs

bash - ¿Cómo ejecutar varios comandos después de xargs-0?



xargs grep (8)

find . -name "filename including space" -print0 | xargs -0 ls -aldF > log.txt find . -name "filename including space" -print0 | xargs -0 rm -rdf

¿Es posible combinar estos dos comandos en uno para que solo se realice 1 búsqueda en lugar de 2?

Sé que para xargs: puede haber formas de hacerlo, lo que puede dar lugar a errores al proceder con los nombres de archivos, incluidos los espacios. Cualquier orientación es muy apreciada.


Creo que todas estas respuestas ya han dado las formas correctas para solucionar este problema. Y probé las 2 soluciones de Jonathan y el modo de Glenn, todo lo cual funcionó muy bien en mi Mac OS X. El método de mouviciel no funcionó en mi sistema operativo tal vez debido a algunas razones de configuración. Y creo que es similar al segundo método de Jonathan (puedo estar equivocado).

Como se menciona en los comentarios al método de Glenn, se necesita un pequeño ajuste. Así que aquí está el comando que probé que funcionó perfectamente para tu información:

find . -name "filename including space" -print0 | xargs -0 -I ''{}'' sh -c ''ls -aldF {} | tee -a log.txt ; rm -rdf {}''

O mejor como lo sugiere Glenn:

find . -name "filename including space" -print0 | xargs -0 -I ''{}'' sh -c ''ls -aldF {} >> log.txt ; rm -rdf {}''


Llego tarde a la fiesta, pero hay una solución más que no se trató aquí: funciones definidas por el usuario. Poner varias instrucciones en una línea es difícil de manejar y puede ser difícil de leer / mantener. El bucle for anterior evita eso, pero existe la posibilidad de exceder la longitud de la línea de comando.

Aquí hay otra manera (sin probar).

function processFiles { ls -aldF "$@" rm -rdf "$@" } export -f processFiles find . -name "filename including space"` -print0 / | xargs -0 bash -c processFiles dummyArg > log.txt

Esto es bastante sencillo, excepto por el "dummyArg" que me causó mucho dolor. Cuando se ejecuta bash de esta manera, los argumentos se leen en

"$0" "$1" "$2" ....

en lugar de lo esperado

"$1" "$2" "$3" ....

Como processFiles {} está esperando que el primer argumento sea " $ 1 ", tenemos que insertar un valor ficticio en " $ 0" .

Footnontes:

  1. Estoy usando algunos elementos de la sintaxis de bash (por ejemplo, " export -f "), pero creo que esto se adaptará a otros shells.
  2. La primera vez que intenté esto, no agregué un argumento ficticio. En su lugar, agregué " $ 0 " a las líneas de argumento dentro de mi función (por ejemplo, ls -aldf "$ 0" "$ @" ). Mala idea. Aparte de los problemas estilísticos, se rompe cuando el comando " encontrar " no devuelve nada. En ese caso, $ 0 se establece en "bash". En su lugar, el uso del argumento ficticio evita todo esto.

Mientras no tenga una nueva línea en sus nombres de archivo, no necesita -print0 para GNU Parallel:

find . -name "My brother''s 12/" records" | parallel ls {}/; rm -rdf {} >log.txt

Mire el video de introducción para obtener más información: http://www.youtube.com/watch?v=OpaiGYxkSuQ


Otra solución:

find . -name "filename including space" -print0 / | xargs -0 -I FOUND echo "$(ls -aldF FOUND > log.txt ; rm -rdf FOUND)"


Puede ejecutar varios comandos después de find utilizando for lugar de xargs :

IFS=$''/n'' for F in `find . -name "filename including space"` do ls -aldF $F > log.txt rm -rdf $F done

El IFS define el Separador de campo interno, que por defecto es <space><tab> <newline>. Si sus nombres de archivo pueden contener espacios, es mejor redefinirlos como se indicó anteriormente.


Si solo desea evitar realizar la find varias veces, puede hacer un tee justo después de la find , guardando la salida de la find en un archivo y luego ejecutando las líneas como:

find . -name "filename including space" -print0 | tee my_teed_file | xargs -0 ls -aldF > log.txt cat my_teed_file | xargs -0 rm -rdf

Otra forma de lograr esta misma cosa (si es que es lo que quieres lograr), es almacenar la salida del find en una variable (suponiendo que no sea TB de datos):

founddata=`find . -name "filename including space" -print0` echo "$founddata" | xargs -0 ls -aldF > log.txt echo "$founddata" | xargs -0 rm -rdf


Solo una variación del enfoque de -print0 sin ese horrible -print0 y -print0 xargs -0 , así es como lo haría:

ls -1 *.txt | xargs --delimiter "/n" --max-args 1 --replace={} sh -c ''cat {}; echo "/n"''

Notas al pie:

  • Sí, sé que las nuevas líneas pueden aparecer en los nombres de archivo, pero que en su sano juicio harían eso
  • Hay opciones cortas para xargs pero para la comprensión del lector, he usado las largas.
  • find -maxdepth 1 -iname "*.txt" ls -1 cuando quiero un comportamiento no recursivo en lugar de find -maxdepth 1 -iname "*.txt" que es un poco más detallado.

find . -name "filename including space" -print0 | xargs -0 -I ''{}'' sh -c ''ls -aldF {} >> log.txt; rm -rdf {}''