Lo que se pasa -execse invocará una vez por cada archivo encontrado con los parámetros de plantilla {}reemplazados por el nombre del archivo actual. El \;final del comando find termina la línea.
El uso de xargsno es realmente necesario en este caso porque necesitamos invocar xmllintuna vez por archivo ya que los nombres de los archivos de entrada y salida deben especificarse dentro de la misma llamada.
xargssería necesario si el comando que se canaliza desde find funciona en varios archivos a la vez y esa lista es larga. No puede hacer eso en este caso, ya que necesita pasar el nombre de archivo único a la --outputopción de xmllint. Sin xargsusted, podría terminar con un error de "Lista de argumentos demasiado larga" si está procesando muchos archivos. xargstambién admite cadenas de reemplazo de archivos con la -Iopción:
Haría lo mismo que el find -execcomando anterior. Si alguna de sus carpetas tiene caracteres extraños en espacios similares, deberá usar las -0opciones de findy xargs. Pero usar xargscon -Iimplica la opción -L 1que significa procesar solo 1 archivo a la vez de todos modos, por lo que también puede usar directamente findcon -exec.
@manatwork gracias por las ediciones - dedos pegajosos; o)
didster
Acabo de ejecutar esto y parece funcionar una delicia! Muchas gracias por la pronta y concisa respuesta!
Harry
2
"Esto fallará si la lista de archivos es demasiado grande": No, no fallará (está procesando un solo archivo a la vez), y de hecho find … -execes la forma más directa de hacerlo.
Gilles 'SO- deja de ser malvado'
@Gilles ¡Buen punto! He actualizado mi respuesta en consecuencia.
didster
1
Esto funciona debido al hecho de que xmllintprimero carga el documento xml completo en la memoria y solo luego analiza / escribe. Esto permite el procesamiento de documentos en el lugar.
Gavenkoa
6
Normalmente ataco estos problemas con una capa de indirección. Escribe un script de shell que haga lo que quieras y llámalo. Sugeriría como comienzo
#! /bin/sh
for file
do
xmllint --format $file > $file.tmp && mv $file.tmp $file
done
Pruébelo a mano en un archivo o dos, luego puede reemplazarlo en los xargs
find . -name "*.xml" -type f | xargs -- xmltidy.sh
find … -exec
es la forma más directa de hacerlo.xmllint
primero carga el documento xml completo en la memoria y solo luego analiza / escribe. Esto permite el procesamiento de documentos en el lugar.Normalmente ataco estos problemas con una capa de indirección. Escribe un script de shell que haga lo que quieras y llámalo. Sugeriría como comienzo
Pruébelo a mano en un archivo o dos, luego puede reemplazarlo en los xargs
fuente