回答:
別のプロセスへのパイピング(これはあなたがやろうとしていることをあなたが言ったことを達成することはできませんが):
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
ます。これは非常に便利です(-print0
andに頼らずにファイル名のスペースなどを扱いますxargs -0
)。
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008は+
マーカーを追加しました。find
これは、適切な数のファイルを単一のコマンド実行に自動的にグループ化することを意味しますxargs
。
ファイル名の問題はオプションがxargs
ない-0
場合の問題であり、「ファイル名が0でも実行」の問題はオプションがある場合とない場合の問題ですが、-0
GNU xargs
には-r
orの--no-run-if-empty
オプションがあり、これを防ぐことができます。また、この表記はプロセス数を削減するものであり、パフォーマンスの違いを測定する可能性が高いわけではありません。したがって、あなたは賢明に書くことができます:
find . -exec grep something {} +
find . -print | xargs grep something
Linuxを使用している場合、またはGNU find
とxargs
コマンドを使用-print0
している場合は、with find
および-0
with 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
は私のために素晴らしく働きました...ありがとう