完全を期すために、コマンド置換についても言及し、これが推奨されない理由を説明します:
cp $(grep -l "pattern" input) directory/
(バッククォート構文 cp `grep -l "pattern" input` directory/
ほぼ同等ですが、時代遅れで扱いにくいです。使用しないでください。)
grep
からの出力の場合、これは失敗します。 空白またはシェルのメタ文字を含むファイル名を生成します。
もちろん、grep
のファイル名が正確にわかっている場合は、これを使用しても問題ありません。 生産可能であり、いずれも問題がないことを確認済みです。ただし、プロダクション スクリプトの場合は、これを使用しないでください。
とにかく、各試合を個別に参照し、それに拡張機能を追加する必要がある OP のシナリオでは、xargs
または while read
いずれにせよ代替手段は優れています。
最悪の場合 (問題のあるファイル名またはファイル名が指定されていないことを意味します)、一致したものを xargs
経由でサブシェルに渡します。 :
grep -l "pattern" input |
xargs -r sh -c 'for f; do cp "$f" "$f.bac"; done' _
...明らかに for
内のスクリプト ループは任意に複雑にすることができます.
理想的なケースでは、実行したいコマンドが単純 (または用途が広い) で、ファイル名の任意の長いリストを単純に渡すことができます。たとえば、GNU cp
-t
を持っています この xargs
の使用を容易にするオプション (-t
オプションを使用すると、宛先ディレクトリを最初に置くことができます コマンドラインで、コマンドの最後に好きなだけファイルを置くことができます):
grep -l "pattern" input | xargs cp -t destdir
に展開されます
cp -t destdir file1 file2 file3 file4 ...
xargs
までのマッチ数 cp
のコマンドラインに収まる 、すべてのファイルを cp
に渡すのに必要な回数だけ繰り返されます . (残念ながら、これは OP のシナリオと一致しません。コピー中にすべてのファイルの名前を変更する必要がある場合は、cp
ごとに 2 つの引数だけを渡す必要があります。 呼び出し:コピー先のソース ファイル名と宛先ファイル名。)
つまり、コマンド置換構文と grep
を使用すると、 本当にを生成します マッチの長いリスト、あなたは ARG_MAX
にぶつかる危険があります および「引数リストが長すぎます」エラー。しかし xargs
cp
に安全に渡すことができる数の引数のみを代わりにコピーすることで、特にこれを回避します 一度に、cp
を実行しています 代わりに、必要に応じて複数回。
xargs
を使用できます :
grep 'pattern' input | xargs -I% cp "%" "%.bac"
$()
を使用できます コマンドの出力を補間します。したがって、 kill -9 $(grep -hP '^\d+$' $(ls -lad /dir/*/pid | grep -P '/dir/\d+/pid' | awk '{ print $9 }'))
を使用できます
Chris Jester-Young の良い答えに加えて、xargs
だと思います は、次のような状況にも適したソリューションです:
grep ... `ls -lad ... | awk '{ print $9 }'` | xargs kill -9
それを作るでしょう。すべて一緒に:
grep -hP '^\d+$' `ls -lad /dir/*/pid | grep -P '/dir/\d+/pid' | awk '{ print $9 }'` | xargs kill -9