
私は奇妙な問題を抱えているxargs。
を持っていますxargsコマンドをエコーすると完璧に動作するにもかかわらず、動作しない構造があります。私のワンライナーは次のとおりです。
exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -0 -I % pdftk % cat output binder1.pdf
そして出力
エラー: ファイルが見つかりません。 エラー: PDF ファイルを開けませんでした: 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf
exiftool
件名タグにDATAという単語を含むすべてのPDFを選択します 。- ファイル名のみを印刷するように
-p exifprintformat
指示します。exiftool
grep
pdfの行のみを選択します 。- 空白を削除します
sed
。 - 最初のものは
xarg
すべての行を1つの文字列にし、2番目のものはbindコマンドを構築します。
exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'|xargs|xargs -I{} echo pdftk {} cat output bidner1.pdf
私は
pdftk 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf cat 出力バインダー1.pdf
それは完璧に機能します。
明らかに、私は何か間違ったことをしています...しかし、何ですか?
答え1
いくつかの間違いと不必要な複雑さがあります:-
- 二重
xargs
呼び出しは、2 番目に 1 行の入力が参照されるため、{}
一致するファイル名すべてを含む単一の文字列に 1 回だけ置換されますが、echo
出力にはこの違いは表示されません (echo a b
と比較してくださいecho "a b"
)。 - 引数は、入力引数の間にnull ( ) 文字が必要であるが、そのような文字がないことを
-0
意味します。これにより、入力が単一のパラメータとして扱われることも強制されます。xargs
'\0'
- 条件が一致したときにファイル名のみを出力すると、1 行に 1 つのファイル名が取得され、または を
xargs
必要とせずに に直接パイプできます。grep
sed
- 残念ながら、
xargs -I
入力行ごとに 1 つのコマンドが強制され、末尾のパラメータを追加するオプションはありませんが、末尾のパラメータを入力ストリームに追加するという簡単な回避策があります。
これは、末尾のパラメータが追加された簡略化されたコマンドです (-if
一致する PDF がない別の条件でテストしました)。
{ exiftool -p '${FileName}' -if '$Subject =~/DATA/i' -q *.pdf; \
echo -e "cat\noutput\nbinder1.pdf"; } | xargs -d'\n' pdftk
このxargs -d'\n'
オプションにより、ファイル名に空白が埋め込まれている場合でもコマンドが機能します。
答え2
xargs のマニュアルページには次のように書かれています:
-I 置換文字列
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.
言い換えれば、" 20170105170516234.pdf 20170105173126944.pdf 20170105173209758.pdf 20170621163418079.pdf
"という単一の引数が残ることになります。
xargs を完全に廃止し、コマンドを次のように並べ替えることをお勧めします。
pdftk $(exiftool -p exifprintformat -if '$Subject =~/DATA/i' -q *.pdf |grep pdf |sed 's/ //g'| tr '\n' ' ') cat output binder1.pdf
これはすべて、ファイル名にスペースが含まれていないことを前提としています (いずれにしても sed を使用してすべてのスペースを削除しているため、安全な前提です)。