web-dev-qa-db-ja.com

複数の引数のxargs置換

デフォルトでは、xargsは入力の多くの行を連結し、指定されたコマンドに渡します。例えば:

echo -e 'line 1\nline 2\nline 3' | xargs echo 

結果は

line 1 line 2 line 3

引数は単一のエコーコマンドに送信されるため(コマンドラインの長さの制限内)。

場合によっては、置換文字列を使用して、引数をコマンドの最後ではなく別の場所に配置する必要があります。

echo -e 'line 1\nline 2\nline 3' | xargs -Ix echo x DONE
line 1 DONE
line 2 DONE
line 3 DONE

現在、xargsは、各echo呼び出しごとに1つの引数のみを置き換えました。これは、manページに「-Iは-L 1 ...を意味する」と記載されているためです。これはおそらく典型的なケースでは正しい動作ですが、それをオーバーライドする方法はあるので、出力としてline 1 line 2 line 3 DONEを取得しますか?

私の例は例示にすぎないことに注意してください-この問題に取り組むxargs以外の方法にはあまり興味がありません。

3
BeeOnRope

それを行うxargsオプションはわかりませんが、bash -cを呼び出すことで同様のことを実現できます。

$ echo -e "line 1\nline    2\nline 3" | xargs bash -c 'echo "${@}" DONE' _
line 1 line 2 line 3 DONE

-Lを指定した場合でも、xargsは引数としてlinesを提供しないことに注意してください。 -dを使用して、改行で項目を区切るように指定することをお勧めします(gnu xargsのみ、私は信じています)。以下を対比してください。

$ echo -e "line 1\nline    2\nline 3" |
  xargs bash -c 'printf "<%s>\n" "${@}" DONE' _
<line>
<1>
<line>
<2>
<line>
<3>
<DONE>

$ echo -e "line 1\nline    2\nline 3" |
  xargs -d\\n bash -c 'printf "<%s>\n" "${@}" DONE' _
<line 1>
<line    2>
<line 3>
<DONE>
3
rici

改行を\nulターミネータに変換してから、xargs -0を使用します

$ echo -ne 'line 1\nline 2\nline 3\n' | tr '\n' '\0' | xargs -0 -Ix echo x DONE
line 1 DONE
line 2 DONE
line 3 DONE
2
hroptatyr

これはどう:

arg=$( echo -e 'line 1\nline 2\nline 3' | xargs )
echo $arg Done.

この構成を使用して、多数の単一PDFから複数ページのPDFファイルを生成しました。

arg=$( find -mmin -60 -type f -name "*.pdf" | xargs )
pdftk $arg cat output AllMyRecentPDFs.pdf
0
bschl