Es posible que desee encadenar llamadas para encontrar (una vez, cuando se enteró, que es posible, que podría ser hoy). Por supuesto, esto solo es posible mientras permanezca en búsqueda. Una vez que se conecta a xargs está 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 solo uno contiene "fiddel".
Supongamos que no lo sabíamos. Buscamos un archivo que coincida con 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 conozca la sintaxis de grep u otro programa para pasar ambas cadenas como condición, pero ese no es el punto. Aquí se puede usar 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 seguir find -exec con otros comandos find, como -ls o -delete o algo similar. Tenga en cuenta que eliminar no solo rm (elimina archivos), sino que rmdir (elimina directorios) también.
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 parens (que necesitan enmascaramiento))).
Así que no te vas de la cadena de búsqueda, lo cual es algo útil. No veo ninguna ventaja en el uso de -xargs, ya que debes tener cuidado al pasar los archivos, que es algo que find no necesita hacer: maneja automáticamente pasar cada archivo como un argumento único para ti.
Si cree que necesita un poco de enmascaramiento para los corchetes find {} , no dude en visitar mi pregunta que solicita evidencia. Mi afirmación es: no lo haces.
find
. ¡Muchas gracias!-exec
forma de hacerloxargs -P4
para que tres de los cuatro núcleos no permanezcan inactivos?La canalización segura de los nombres de archivos
xargs
requiere que sufind
soporte sea compatible con la-print0
opción y quexargs
tenga la opción correspondiente para leerlo (--null
o-0
). De lo contrario, los nombres de archivo con caracteres no imprimibles o barras invertidas o comillas o espacios en blanco en el nombre pueden causar un comportamiento inesperado. Por otro lado,find -exec {} +
está en la especificación POSIXfind
, por lo que es portátil, y es casi tan seguro comofind -print0 | xargs -0
, y definitivamente más seguro quefind | xargs
. Me gustaría recomendar no hacerfind | xargs
sin-print0
.fuente
find … -exec … {} +
OpenBSD es, que solo adquirió esta característica con la versión 5.1 lanzada en 2012. Todos los BSD han tenido-print0
durante varios años, incluso OpenBSD (aunque también resistió esa característica por un tiempo). Solaris, por otro lado, se adhiere a las funciones POSIX, por lo que obtienes-exec +
y no-print0
.-print0
es un dolor y, aunque se puede argumentarxargs --delimiter "\n"
que no es equivalente, nunca he usado el primero después de descubrir el último.-0
es más doloroso que--delimiter "\n"
.-0
, GNUxargs
debe-r
evitar ejecutar el comando si no hay entrada.| xargs -r0 cmd
es quecmd
el stdin se ve afectado (dependiendo de laxargs
implementación, es/dev/null
o la tubería.)Si usa el
-exec ... ;
formulario (recordando escapar del punto y coma), está ejecutando el comando una vez por nombre de archivo. Si lo usa-print0 | xargs -0
, ejecuta múltiples comandos por nombre de archivo. Definitivamente, debe usar el-exec +
formulario, que coloca varios archivos en una sola línea de comando y es mucho más rápido cuando hay una gran cantidad de archivos involucrados.Una gran ventaja de usar
xargs
es la capacidad de ejecutar múltiples comandos en paralelo usandoxargs -P
. En sistemas multinúcleo, eso puede proporcionar un gran ahorro de tiempo.fuente
-P
lugar de-p
. Tenga en cuentaxargs -P
que no está en el estándar POSIX, mientras que lofind -exec {} +
es, lo que es importante si desea la portabilidad.find /tmp/ -exec ls "{}" +
funciona bien.-exec
de tanto tiempo (soy masoquista, ni siquiera uso comillas para escapar{}
, siempre escribo\{\}
; no preguntes), todo parece que debe escaparse ahora.find /tmp/ -exec ls {} +
que no funcionaría.bash
comencé a aceptar las llaves literalmente. Estoy bastante seguro de que al menos uno de los viejos proyectiles que he usado arrojó silbidos si no se escaparon los frenos.Con respecto al rendimiento, pensé que eso
-exec … +
sería simplemente mejor porque es una herramienta única que hace todo el trabajo, pero una parte de la documentación de GNU findutil dice que-exec … +
podría ser menos eficiente en algunos casos:No estaba exactamente seguro de lo que eso significaba, así que pregunté en el chat dónde derobert lo explicó como:
(Formateando por mí)
Entonces ahí está eso. Pero si el rendimiento realmente importa, tendría que hacer una evaluación comparativa realista o, más bien, incluso preguntarse si incluso querría usar shell para tales casos.
Aquí, en este sitio, creo que es mejor aconsejar a las personas que usen 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).fuente