Linuxシェル xargsで引数を任意の位置に配置したい

Linux terminal

パイプで出力を渡す

cat samplefile
Tom
Mike
John

samplefileというファイルがあるとします。

パイプでgrepに渡す

cat samplefile | grep John
John

パイプ左側の出力をgrepに渡してJohnでフィルタリングします。

2番目の引数としてファイルを指定する

grep John samplefile
John

2番目の引数としてファイルを指定する事も可能です。

xargs

背景はZABBIXで検知したログをawkやcutで切り出して、パイプの出力を特定のファイルでgrepに掛けて結果を別のログに出力したかった事にあります。

echo John | xargs echo
John

パイプの左側の出力Johnが、xargsによってパイプ右側のechoの引数になってJohnが表示されます。
パイプ左側の処理は分かりやすくする為にechoにしています。

xargsでgrepにファイル指定で引数を渡そうとするとエラーになる

echo John | xargs grep samplefile
grep: John: そのようなファイルやディレクトリはありません

上の実行例ではgrepとsamplefileの間に、パイプ左側の出力が最初の引数として入る事を期待していますが、エラーになります。

パイプでxargsにデータを渡すとデフォルトでは最後の部分に引数として渡されてしまう仕様の様です。

-i オプションで引数を任意の位置に配置する

echo John | xargs -i grep {} samplefile
John

-i オプションをxargsに使い、パイプ左側の出力を引数として配置したい場所に{}を配置します。
これでgrepの後の部分に引数が渡される様になります。

readを使う方法もある

echo John | (read v ; grep $v samplefile)
John

readで変数vに読み込ませてからセミコロンで繋ぎ、grep $v samplefileしています。
()で囲む必要があります。
xargs -i の方がスマートに感じます。

シェルのワンライナーがキマるとすっきりしませんか? 極めたい方はこちら↓

TwitterFacebookLinkedInHatenaPocketCopy Link