Estoy manipulando una gran cantidad de archivos XML dispersos en una estructura de directorios anidados.
Intenté lo siguiente:
$ find . -name "*.xml" -type f | xargs -- xmllint --format
El problema es que genera la salida XML formateada en la pantalla, pero no cambia el archivo.
¿Cómo puedo cambiar este comando para que se cambie el contenido real del archivo?
Respuesta aceptada:
Esto se puede hacer desde find
directamente usando -exec
:
find . -name "*.xml" -type f -exec xmllint --output '{}' --format '{}' \;
Lo que se pasa a -exec
se invocará una vez por archivo encontrado con los parámetros de plantilla {}
siendo reemplazado con el nombre de archivo actual. El \;
al final del comando de búsqueda solo termina la línea.
El uso de xargs
no es realmente necesario en este caso porque necesitamos invocar xmllint
una vez por archivo, ya que los nombres de los archivos de entrada y salida deben especificarse dentro de la misma llamada.
xargs
sería necesario si el comando que se canaliza desde find estuviera trabajando en varios archivos a la vez y esa lista fuera larga. No puede hacer eso en este caso, ya que necesita pasar el nombre de archivo único a --output
opción de xmllint
. Sin xargs
podría terminar con un error de "Lista de argumentos demasiado larga" si está procesando muchos archivos. xargs
también admite cadenas de reemplazo de archivos con -I
opción:
find . -name "*.xml" -type f | xargs -I'{}' xmllint --output '{}' --format '{}'
Haría lo mismo que find -exec
comando de arriba. Si alguna de sus carpetas tiene caracteres extraños en espacios similares, deberá usar -0
opciones de find
y xargs
. Pero usando xargs
con -I
implica la opción -L 1
lo que significa que solo procesa 1 archivo a la vez de todos modos, por lo que también puede usar directamente find
con -exec
.