私は実行してfindから、ファイルのリストを取得しています。cat( cat がこれらすべてのファイルの内容を表示するように) などの別のユーティリティにパイプして、基本的にgrepこれらのファイルから何かを取得する必要があります。
15 に答える
別のプロセスへのパイプ (これは、あなたがやろうとしていると言ったことを達成しませんが):
command1 | command2これにより、command1 の出力が command2 の入力として送信されます。
-execでfind(これはあなたがやりたいことをします-しかし、に固有ですfind)find . -name '*.foo' -exec cat {} \;( と の間のすべては
find、-exec既に使用していた検索述語です。{}は、見つかった特定のファイルをコマンドに置き換えます (cat {}この場合)。はコマンド\;を終了し-execます。)あるプロセスの出力をコマンドライン引数として別のプロセスに送信する
command2 `command1`例えば:
cat `find . -name '*.foo' -print`(これらは通常の引用符ではなくバッククォートであることに注意してください(キーボードのチルダ ~ の下)。)これにより、コマンドライン引数として
command1intoの出力が送信されます。command2ただし、スペース (改行など) を含むファイル名は個別の引数に分割されることに注意してください。
現代版
POSIX 2008 は+マーカーを追加しましたfind。これは、妥当な数のファイルを 1 つのコマンド実行に自動的にグループ化することを意味しますxargs。
- ファイル名の奇妙な文字について心配する必要はありません。
- コマンドがファイル名なしで呼び出されることを心配する必要はありません。
ファイル名の問題はオプションxargsなしの問題で-0あり、「ファイル名がなくても実行する」問題は-0オプションの有無にかかわらず問題です — しかし、GNUxargsにはそれを防ぐ-rorオプションがあります。--no-run-if-emptyまた、この表記はプロセスの数を減らしますが、パフォーマンスの違いを測定する可能性は低いです。したがって、賢明にも次のように書くことができます。
find . -exec grep something {} +
クラシックバージョン
find . -print | xargs grep something
Linux を使用している場合、または GNUfindとxargsコマンドを使用している場合-print0は、 withfindおよび-0withを使用して、xargsスペースやその他の奇妙な文字を含むファイル名を処理します。
find . -print0 | xargs -0 grep something
からの結果を微調整するgrep
ファイル名(テキストのみ)が必要ない場合は、適切なオプションを追加しますgrep(通常は-h「見出し」を抑制します)。ファイル名が出力されることを絶対に保証するにはgrep(ファイルが 1 つしか見つからない場合や、最後の呼び出しでファイル名が 1 つしか指定されていない場合でも)、少なくとも 2 つのファイル名が常に存在するようにコマンド ラインにgrep追加/dev/nullします。xargs
findコマンドから返されたファイルのリストをコマンドに渡す方法はいくつかありますが、cat技術的にはすべてがパイピングを使用するわけではなく、実際に に直接パイプする方法はありませんcat。
最も簡単なのは、バッククォート (
`) を使用することです。cat `find [whatever]`これにより、 の出力が
find取得され、効果的に のコマンド ラインに配置されcatます。find出力が多すぎる場合 (コマンドラインに収まりきらない場合)、または出力に特殊文字 (スペースなど) が含まれる場合、これはうまく機能しません。を含む一部のシェルでは、バッククォートの代わりに
bash使用できます。$()cat $(find [whatever])これは移植性が低くなりますが、ネスト可能です。それを除けば、バックティックとほとんど同じ注意事項があります。
見つかったものに対して他のコマンドを実行することは の一般的な用途であるため
find、 find には、-exec見つかったファイルごとにコマンドを実行するアクションがあります。find [whatever] -exec cat {} \;は
{}ファイル名のプレースホルダーで、\;はコマンドの終わりを示します ( の後に他のアクションを指定することもでき-execます)。これは、複数のファイル名を渡す
cat単一のインスタンスを実行するのではなく、単一のファイルごとに 1 回実行されます。構文も入力するのが面倒です。セミコロンはシェルにとって特別なので、セミコロンをエスケープする必要があります。catcatの一部のバージョン
find(特に GNU バージョン)では、 の追加モードを使用;して を置き換えて、のインスタンスをより少なく実行できます。+-execcatfind [whatever] -exec cat {} +これにより、複数のファイル名が の各呼び出しに渡され
cat、より効率的になります。ただし、これは単一の呼び出しを使用することが保証されていないことに注意してください。コマンドラインが長すぎる場合、引数は の複数の呼び出しに分散されます
cat。catこれはおそらく大したことではありませんが、他のいくつかのコマンドでは、望ましくない方法で動作が変わる可能性があります。Linux システムでは、コマンド ラインの長さの制限が非常に大きいため、他の一部の OS と比較して、複数の呼び出しに分割されることはほとんどありません。クラシック/ポータブル アプローチは、次を使用すること
xargsです。find [whatever] | xargs catxargs指定されたコマンド (catこの場合は ) を実行し、stdin から読み取った内容に基づいて引数を追加します。と同様-execに+、必要に応じてコマンドラインを分割します。つまり、find出力が多すぎると、cat複数回実行されます。前述のセクションで説明した-execように、この分割によって異なる動作が発生するコマンドがいくつかあります。このように使用すると、空白を区切り文字として使用するだけxargsなので、ファイル名のスペースに問題があることに注意してください。xargs最も堅牢で、移植性があり、効率的な方法では、次のものも使用します
xargs。find [whatever] -print0 | xargs -0 cat-print0フラグは、ファイル名の間に (ヌル文字) 区切り文字findを使用するように指示し、フラグはこれらの区切り文字を期待するように指示します。これは...アプローチとほとんど同じ動作をしますが、より移植性があります (残念ながらより冗長です)。\0-0xargs\0-exec+
これを (bash を使用して) 達成するには、次のようにします。
cat $(find . -name '*.foo')
これは「コマンド置換」として知られており、デフォルトで改行が削除されます。これは非常に便利です。
詳細はこちら
私にはシェルスクリプトの仕事のように思えます:
for file in 'find -name *.xml'
do
grep 'hello' file
done
またはそのようなもの
興味のあるコンテンツを含むファイル名を見つける方法は次のとおりです。ファイル名のスペースも適切に処理する単一の bash 行だけです。
find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done
私は次のようなものを使用します:
find . -name <filename> -print0 | xargs -0 cat | grep <word2search4>
ファイル パス/名前の空白を正しく処理するには、「find」の「」引数と「xargs」の「」引数が必要です-print0。-0
一般的な使用のための私のショットは次のとおりです。
grep YOURSTRING `find .`
ファイル名を出力します
bashでは、次のことが適切です。
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
/dirこれにより、ディレクトリ内のすべてのファイルが検索されxargs、ファイル名がに安全にパイプされ、安全にドライブされgrepます。
xargsに何千ものファイルがある場合、スキップすることはお勧めできません/dir。cat引数リストの長さが長すぎるために壊れます。xargsあなたのためにそれをすべて整理します。
の-print0引数は、スペースを含むファイル名を適切に処理するための引数とfind一致します。の引数を使用すると、コマンドラインで必要な場所にファイル名を挿入できます。角かっこは、からコマンドにパイプされたファイル名に置き換えられます。-0xargs-ixargscatcatfind
find コマンドには、このような場合に使用できる -exec 引数があり、それを使用して直接 grep を実行できます。
例(ここから、このページの他の良い例):
find . -exec grep "www.athabasca" '{}' \; -print
サーバー上のディレクトリ /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 ^# {} \;
ファイル内のテキストを検索しようとしていますか? そのためには単にgrepを使用できます...
grep searchterm *