buscar -exec + vs buscar | xargs: ¿cuál elegir?

buscar -exec + vs buscar | xargs: ¿cuál elegir?

Entiendo que -execpueden 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 finddebieron haber realizado las optimizaciones apropiadas. ¿Estoy en lo correcto?

Respuesta1

La canalización segura de nombres de archivos xargsrequiere que findadmita la -print0opción y xargstenga la opción correspondiente para leerlo ( --nullo -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 elfindespecificació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 -orinterruptor (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 xargses 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 de xargs; por ejemplo, xargspermite 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, la find ... -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 -print0acción '' en cualquier caso.

No estaba exactamente seguro de lo que eso significaba, así que pregunté en el chat dóndederobertlo explicó como:

findProbablemente 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).

información relacionada