すべての.txt
ファイルを検索して、いくつかの文字列を検索するとします。私はします:
find ./ -type f -name "*.txt" -exec egrep -iH 'something' '{}' \;
次のように、より複雑なフィルタリングを行う場合はどうなりますか。
egrep something file.txt | egrep somethingelse | egrep other
Find -execの内部? (または類似)
必要なときに簡単に入力できる解決策を探していることを覚えておいてください。これはシェルスクリプトを使用して数行で実行できることを知っていますが、それは私が探しているものではありません。
Find内から実行する必要がある場合は、シェルを呼び出す必要があります。
find ./ -type f -name "*.txt" -exec sh -c 'grep -EiH something "$1" | grep -E somethingelse | grep -E other' sh {} \;
他の選択肢には、代わりにxargs
を使用することが含まれます。
find ./ -type f -name "*.txt" |
xargs -I{} grep -EiH something {} |
grep -EiH somethingelse |
grep -EiH other
または、任意のファイル名の方がはるかに安全です(find
が-print0
をサポートしている場合):
find ./ -type f -name "*.txt" -print0 |
xargs -0 grep -EiH something {} |
grep -Ei somethingelse |
grep -Ei other
または、代わりにシェルループを使用することもできます。
find ./ -type f -name "*.txt" -print0 |
while IFS= read -d '' file; do
grep -Ei something "$file" |
grep -Ei somethingelse |
grep -Ei other
done
編集:この答えは推奨されませんですが、bashスクリプトでの潜在的に危険な落とし穴の比較と説明のためにここに残されています。
bash
(または別のシェル)を-exec
コマンド:
find -type -f -name "*.txt" -exec bash -c 'egrep -iH something "{}" | egrep somethingelse | egrep other' \;
この方法を使用することの欠点の1つは、コマンドが複雑になるにつれて、ネストされた引用の問題が発生する可能性が高くなることです。それを避けたい場合は、for
ループに分割できます。
for i in $(find -type -f -name "*.txt"); do
if egrep -iH something "$i" | egrep somethingelse | egrep other; then
echo "Found something: $i"
fi
done