
tengo un problema extraño conxargos.
Yo tengo unxargosconstrucción que no funciona, aunque cuando repito el comando, funciona perfectamente. Mi única línea es la siguiente:
exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -0 -I % pdftk % cat output binder1.pdf
y la salida
Error: No se puede encontrar el archivo. Error: No se pudo abrir el archivo PDF: 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf
- Selecciona
exiftool
todos los pdf que contienen la palabra DATOS en la etiqueta de asunto, - Las
-p exifprintformat
instruccionesexiftool
para imprimir solo el nombre del archivo, - Selecciona
grep
solo las líneas con pdf, - El
sed
elimina espacios en blanco, - El primero
xarg
convierte todas las líneas en una sola cadena y el segundo construye el comando de vinculación) cuando ejecuto
exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -I{} echo pdftk {} cat salida binder1.pdf
yo obtengo
pdftk 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf carpeta de salida cat1.pdf
que funciona perfectamente.
Evidentemente estoy haciendo algo mal... ¿Pero qué?
Respuesta1
Hay varias cosas mal y complejidad innecesaria: -
- La llamada doble
xargs
significa que la segunda ve una sola línea de entrada, por lo que{}
se sustituye solo una vez con una sola cadena que comprende todos los nombres de archivos coincidentes, peroecho
no muestra esta diferencia en la salida (compáreseecho a b
conecho "a b"
). - El
-0
argumento significa quexargs
se necesita un'\0'
carácter nulo ( ) entre los argumentos de entrada, y no hay ninguno; esto también obliga a que la entrada se trate como un único parámetro. - Al generar solo el nombre del archivo cuando la condición coincide, obtiene un nombre de archivo por línea, al que se puede canalizar directamente
xargs
sin la necesidad degrep
osed
. - Desafortunadamente,
xargs -I
fuerza un comando por línea de entrada y no hay opción para agregar parámetros finales, pero hay una solución simple: agregar los parámetros finales al flujo de entrada.
Este es un comando simplificado con los parámetros finales agregados (lo probé con una -if
condición diferente y no tenía ningún archivo PDF que coincidiera): -
{ exiftool -p '${FileName}' -if '$Subject =~/DATA/i' -q *.pdf; \
echo -e "cat\noutput\nbinder1.pdf"; } | xargs -d'\n' pdftk
La xargs -d'\n'
opción hace que el comando funcione cuando los nombres de los archivos tienen espacios en blanco incrustados.
Respuesta2
La página de manual de xargs dice:
-reemplazo-str
Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1.
En otras palabras, terminarás con un único argumento llamado " 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf
"
Sugiero deshacerse de xargs por completo y reordenar su comando de esta manera:
pdftk $(exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'| tr '\n' ' ') cat output binder1.pdf
Todo esto supone que no tienes espacios en tus nombres de archivos (suposición segura ya que de todos modos estabas eliminando todos los espacios con sed).