
Entiendo que -exec
pueden elegir una +
opción para imitar el comportamiento de xargs
. ¿Hay alguna situación en la que prefieras una forma sobre la otra?
Personalmente tiendo a preferir la primera forma, aunque sólo sea para evitar el uso de una pipa. Supongo que seguramente los desarrolladores find
debieron haber realizado las optimizaciones apropiadas. ¿Estoy en lo correcto?
Respuesta1
La canalización segura de nombres de archivos xargs
requiere que find
admita la -print0
opción y xargs
tenga la opción correspondiente para leerlo ( --null
o -0
). De lo contrario, los nombres de archivos con caracteres no imprimibles, barras invertidas, comillas o espacios en blanco en el nombre pueden provocar un comportamiento inesperado. Por otra parte, find -exec {} +
está en elfind
especificación POSIX, por lo que es portátil y tan seguro como find -print0 | xargs -0
, y definitivamente más seguro que find | xargs
. Yo lo recomiendonuncaprescindir .find | xargs
-print0
Respuesta2
Es posible que desee encadenar llamadas para buscar (una vez, cuando supo que es posible, lo que podría ser hoy). Por supuesto, esto sólo es posible mientras permanezcas en la búsqueda. Una vez que canalizas a xargs, queda fuera de alcance.
Pequeño ejemplo, dos archivos a.lst y b.lst:
cat a.lst
fuddel.sh
fiddel.sh
cat b.lst
fuddel.sh
No hay truco aquí, simplemente el hecho de que ambos contienen "fuddel" pero sólo uno contiene "fiddel".
Supongamos que no lo sabíamos. Buscamos un archivo que cumpla 2 condiciones:
find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls
192097 4 -rw-r--r-- 1 stefan stefan 20 Jun 27 17:05 ./a.lst
Bueno, tal vez conozcas la sintaxis de grep u otro programa para pasar ambas cadenas como condición, pero ese no es el punto. Aquí se puede utilizar cualquier programa que pueda devolver verdadero o falso, dado un archivo como argumento; grep fue solo un ejemplo popular.
Y tenga en cuenta que puede seguirbuscar -execcon otros comandos de búsqueda, como-lso-borraro algo similar. Tenga en cuenta que eliminar no solo elimina rm (elimina archivos), sino también rmdir (elimina directorios).
Dicha cadena se lee como una combinación AND de comandos, siempre que no se especifique lo contrario (es decir, con un -or
interruptor (y pares (que necesitan enmascaramiento))).
Por lo tanto, no abandonará la cadena de búsqueda, lo cual es útil. No veo ninguna ventaja en usar -xargs, ya que hay que tener cuidado al pasar los archivos, algo que find no necesita hacer: automáticamente maneja pasar cada archivo como un único argumento para usted.
Si cree que necesita algo de enmascaramiento para los hallazgos{} llaves, no dude en visitar mi pregunta que solicita pruebas. Mi afirmación es: no es así.
Respuesta3
Si usa el -exec ... ;
formulario (recordando escapar del punto y coma), ejecutará el comando una vez por nombre de archivo. Si usa -print0 | xargs -0
, ejecuta múltiples comandos por nombre de archivo. Definitivamente deberías usar el -exec +
formulario, que coloca varios archivos en una sola línea de comando y es mucho más rápido cuando se trata de una gran cantidad de archivos.
Una gran ventaja de usar xargs
es la capacidad de ejecutar múltiples comandos en paralelo usando xargs -P
. En sistemas multinúcleo, esto puede suponer un enorme ahorro de tiempo.
Respuesta4
En cuanto al rendimiento pensé que-exec … +
sería simplemente mejor porque es una única herramienta que hace todo el trabajo, perouna parte de la documentación de GNU findutildice que -exec … +
podría ser menos eficiente en algunos casos:
[encontrar con
-exec … +
]puede ser menos eficiente que algunos usos dexargs
; por ejemplo,xargs
permite crear nuevas líneas de comando mientras el comando anterior aún se está ejecutando y le permite especificar una cantidad de comandos para ejecutar en paralelo. Sin embargo, lafind ... -exec ... +
construcción tiene la ventaja de una amplia portabilidad. GNU findutils no admitió '-exec ... +
' hasta la versión 4.2.12[Enero de 2005]; una de las razones de esto es que ya tenía la-print0
acción '' en cualquier caso.
No estaba exactamente seguro de lo que eso significaba, así que pregunté en el chat dóndederobertlo explicó como:
find
Probablemente podría continuar buscando el siguiente lote de archivos mientras se-exec … +
ejecuta, pero no es así.
find … | xargs …
lo hace, porque entonces la búsqueda es un proceso diferente y continúa ejecutándose hasta que el búfer de tubería se llena
(Formateado por mí.)
Entonces ahí está eso. Pero si el rendimiento realmente importa, tendría que realizar una evaluación comparativa realista o incluso preguntarse si desea utilizar Shell para tales casos.
Aquí en este sitio creo que es mejor recomendar a las personas que utilicen el -exec … +
formulario siempre que sea posible porque es más simple y por las razones mencionadas en las otras respuestas aquí (por ejemplo, manejar nombres de archivos extraños sin tener que pensar mucho).