
Ich habe ein seltsames Problem mitxargs.
Ich habe einxargsKonstrukt, das nicht funktioniert, obwohl es perfekt funktioniert, wenn ich den Befehl wiedergebe. Mein Einzeiler ist der folgende:
exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -0 -I % pdftk % cat output binder1.pdf
und die Ausgabe
Fehler: Datei konnte nicht gefunden werden. Fehler: PDF-Datei konnte nicht geöffnet werden: 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf
- Das
exiftool
wählt alle PDFs aus, die das Wort DATA im Betreff-Tag enthalten. - Die
-p exifprintformat
Anweisung,exiftool
nur den Dateinamen auszudrucken, - Das
grep
wählt nur die Zeilen mit pdf aus, - Das
sed
entfernt Leerzeichen, - Die erste
xarg
macht alle Zeilen zu einem String und die zweite erstellt den Bind-Befehl), wenn ich
exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -I{} echo pdftk {} cat Ausgabe binder1.pdf
Ich bekomme
pdftk 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf cat-Ausgabe binder1.pdf
was perfekt funktioniert.
Offensichtlich mache ich etwas falsch ... Aber was?
Antwort1
Mehrere Dinge sind falsch und es besteht eine unnötige Komplexität: -
- Der doppelte
xargs
Aufruf bedeutet, dass der zweite Aufruf eine einzelne Eingabezeile sieht und diese daher{}
nur einmal durch eine einzelne Zeichenfolge ersetzt wird, die alle übereinstimmenden Dateinamen enthält.echo
In der Ausgabe zeigt sich dieser Unterschied jedoch nicht (vergleichen Sieecho a b
mitecho "a b"
). - Das
-0
Argument bedeutet, dass zwischen den Eingabeargumentenxargs
ein Nullzeichen () erforderlich ist , es jedoch keines gibt. Dadurch wird auch erzwungen, dass die Eingabe als einzelner Parameter behandelt wird.'\0'
- Indem nur der Dateiname ausgegeben wird, wenn die Bedingung erfüllt ist, erhalten Sie einen Dateinamen pro Zeile, an den direkt weitergeleitet werden kann, ohne dass oder
xargs
erforderlich ist .grep
sed
- Leider
xargs -I
wird ein Befehl pro Eingabezeile erzwungen und es besteht keine Möglichkeit, nachfolgende Parameter hinzuzufügen. Es gibt jedoch eine einfache Problemumgehung: Fügen Sie die nachfolgenden Parameter zum Eingabestrom hinzu.
Dies ist ein vereinfachter Befehl mit hinzugefügten nachfolgenden Parametern (ich habe ihn unter einer anderen -if
Bedingung getestet, da ich keine übereinstimmenden PDFs hatte): -
{ exiftool -p '${FileName}' -if '$Subject =~/DATA/i' -q *.pdf; \
echo -e "cat\noutput\nbinder1.pdf"; } | xargs -d'\n' pdftk
Die xargs -d'\n'
Option bewirkt, dass der Befehl funktioniert, wenn die Dateinamen eingebettete Leerzeichen enthalten.
Antwort2
Auf der Manpage für xargs heißt es:
-I ersetze-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.
Mit anderen Worten, Sie erhalten am Ende ein einzelnes Argument namens " 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf
"
Ich schlage vor, xargs ganz wegzulassen und Ihren Befehl etwa so neu anzuordnen:
pdftk $(exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'| tr '\n' ' ') cat output binder1.pdf
Dies alles setzt voraus, dass Ihre Dateinamen keine Leerzeichen enthalten (sichere Annahme, da Sie ohnehin alle Leerzeichen mit sed entfernt haben).