回答:
別のプロセスへのパイピング(これはあなたがやろうとしていることをあなたが言ったことを達成することはできませんが):
command1 | command2
これにより、command1の出力がcommand2の入力として送信されます。
-exec上でfind(これは、あなたがやりたいと思っている何だろう-しかし、固有のものですfind)
find . -name '*.foo' -exec cat {} \;
(すべては間findと-exec、あなたが既に使用していた検索述語がある。 {}あなたは、コマンドの中に見つかった特定のファイル(代用しますcat {}この場合は)、\;終了している-execコマンドを使用します。)
あるプロセスの出力をコマンドライン引数として別のプロセスに送信する
command2 `command1`
例えば:
cat `find . -name '*.foo' -print`
(これらは通常の引用符ではなく、バッククォートであることに注意してください(キーボードのチルダ〜の下))これにより、の出力がコマンドライン引数として送信command1さcommand2れます。ただし、スペースを含むファイル名(改行など)は個別の引数に分割されます。
find、次のように記述できることに注意してください。はfind . -name '*.foo' -exec cat {} +、が便利なだけのファイル名を1つのコマンド呼び出しにグループ化する+ことを示していfindます。これは非常に便利です(-print0andに頼らずにファイル名のスペースなどを扱いますxargs -0)。
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008は+マーカーを追加しました。findこれは、適切な数のファイルを単一のコマンド実行に自動的にグループ化することを意味しますxargs。
ファイル名の問題はオプションがxargsない-0場合の問題であり、「ファイル名が0でも実行」の問題はオプションがある場合とない場合の問題ですが、-0GNU xargsには-rorの--no-run-if-emptyオプションがあり、これを防ぐことができます。また、この表記はプロセス数を削減するものであり、パフォーマンスの違いを測定する可能性が高いわけではありません。したがって、あなたは賢明に書くことができます:
find . -exec grep something {} +
find . -print | xargs grep something
Linuxを使用している場合、またはGNU findとxargsコマンドを使用-print0している場合は、with findおよび-0with xargsを使用して、スペースやその他の奇妙な文字を含むファイル名を処理します。
find . -print0 | xargs -0 grep something
grepファイル名(テキストのみ)が必要ない場合は、適切なオプションをgrep(通常は-h「見出し」を抑制するために)追加します。によってファイル名が確実に出力されるようにするにはgrep(ファイルが1つしか見つからない場合、またはの最後の呼び出しでgrepファイル名が1つしか与えられない場合でも)、コマンドラインに追加/dev/nullして、xargs常に少なくとも2つのファイル名が存在するようにします。
xargs grep something。
find、の標準入力にパイプされますxargs。xargsプログラムは、ホワイトスペース(空白、改行、タブなど)で、標準入力、分割入力を読み取り、コマンドに単語の数を追加grep somethingし、コマンドラインを実行します。xargs次に、入力を読み取り、入力がなくなるまでコマンドを実行し続けます。xargs指定さgrepれた入力に対して必要なだけコマンドを実行します(findこの例では)。
/dev/nullてエラーメッセージを失います。
findコマンドから返されたファイルのリストをコマンドに渡す方法はいくつかありますが、cat技術的にはすべてがパイピングを使用するわけではなく、実際に直接にパイピングするものはありませんcat。
最も簡単なのは、バックティック(`)を使用することです。
cat `find [whatever]`
これにより、の出力がfind取得され、事実上のコマンドラインに配置されcatます。find出力が多すぎる(コマンドラインに収まりきらない)場合、または出力に特殊文字(スペースなど)が含まれる場合、これはうまく機能しません。
を含む一部のシェルではbash、$()バックティックの代わりに使用できます。
cat $(find [whatever])
これは移植性は低くなりますが、ネスト可能です。それを除けば、バックティックとほとんど同じ警告があります。
見つかったものに対して他のコマンドを実行することはの一般的な使用方法であるためfind、findには、-exec見つかったファイルごとにコマンドを実行するアクションがあります。
find [whatever] -exec cat {} \;
{}ファイル名のプレースホルダで、\;マークコマンドの終わり(これは、後に他のアクションを持つことが可能です-exec。)
これは、複数のファイル名を渡すcat単一のインスタンスを実行するのではなく、すべてのファイルに対して1回実行されcatます。これは非効率的であり、一部のコマンドに対して希望する動作をしない場合があります(は問題ありませんcat)。構文もタイプするのが面倒です-セミコロンはシェルにとって特別なので、セミコロンをエスケープする必要があります!
の一部のバージョンfind(特にGNUバージョン)では、を置き換え;て+、-execの追加モードを使用して、以下のインスタンスを実行しますcat。
find [whatever] -exec cat {} +
これによりcat、の呼び出しごとに複数のファイル名が渡されるため、より効率的です。
ただし、これは単一の呼び出しの使用を保証するものではないことに注意してください。コマンドラインが長すぎる場合、引数はの複数の呼び出しに分散されますcat。以下のためにcat、このおそらく大したことではないですが、いくつかの他のコマンドのために、これは望ましくない方法で動作を変更することがあります。Linuxシステムでは、コマンドラインの長さの制限が非常に大きいため、他の一部のOSと比較して、複数の呼び出しに分割することは非常にまれです。
古典的/ポータブルなアプローチは以下を使用することxargsです:
find [whatever] | xargs cat
xargs指定されたコマンド(catこの場合は)を実行し、標準入力から読み取った内容に基づいて引数を追加します。と同様-execに+、必要に応じてコマンドラインを分割します。つまり、find出力が多すぎると、cat複数回実行されます。前述のセクションで述べたように、-execこの分割により異なる動作が発生する可能性のあるコマンドがいくつかあります。xargsこのようにxargs使用すると、空白を区切り文字として使用するだけなので、ファイル名のスペースに問題が発生することに注意してください。
最も堅牢で、移植性があり、効率的な方法でも使用しますxargs。
find [whatever] -print0 | xargs -0 cat
-print0フラグが伝えfind使用する\0(ヌル文字)をファイル名の間の区切り文字を、そして-0フラグが伝えxargsこれらの期待する\0区切り文字を。これは-exec...の+アプローチとほとんど同じ動作をしますが、移植性は高くなります(ただし、残念ながら詳細度は高くなります)。
lsでも機能するため、優れています。
$()また、以外のコマンドでも機能しますfind 。
私にはシェルスクリプトの仕事のように聞こえます:
for file in 'find -name *.xml'
do
grep 'hello' file
done
またはそのようなもの
findコマンドには、このようなものに使用できる-exec引数があり、それを直接使用してgrepを実行できます。
例(ここから、このページの他の良い例):
find . -exec grep "www.athabasca" '{}' \; -print
bashでは、以下が適切です。
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
これにより、/dirディレクトリ内のすべてのファイルが検索されxargs、安全にファイル名がにパイプされます。grepます。
にxargs何千ものファイルがある場合、スキップはお勧めできません/dir。cat引数リストが長すぎるために壊れます。xargsそれをすべて整理してくれます。
スペースを含むファイル名を適切に処理するための-print0引数とfindメッシュするための-0引数xargs。-i引数は、xargsあなたが必要なファイル名を挿入することができますcatコマンドラインを。大括弧は、catからコマンドにパイプされたファイル名に置き換えられますfind。
これは私のために働く
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
これにより、ファイルの名前と内容のみが再帰的に出力されます。
find . -type f -printf '\n\n%p:\n' -exec cat {} \;
編集(改良版): これはテキスト(ASCII)ファイルの名前と内容を再帰的にのみ印刷します。
find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'
もう1つの試み
find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
ファイル内のテキストを見つけようとしていますか?あなたは単にそのためにgrepを使うことができます...
grep searchterm *
ディレクトリ/ ghiおよび/ jklにあるサーバー上のすべてのabc.defファイルの内容をリストおよび表示するには
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;
コメント付きのエントリを持つabc.defファイルをリストして表示するには、ディレクトリ/ ghiおよび/ jkl内のそれらのエントリを参照してください。
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
find -name '*.foo' -printは私のために素晴らしく働きました...ありがとう