現在のディレクトリで、ファイル名と内容を印刷したいと思います。ファイル名や内容を別々に印刷できます
find . | grep "file_for_print" | xargs echo
find . | grep "file_for_print" | xargs cat
しかし、私が欲しいのは、次のようにそれらを一緒に印刷することです。
file1
line1 inside file1
line2 inside file1
file2
line1 inside file2
line2 inside file2
引数として複数のコマンドを含むxargs を読んで、試しました
find . | grep "file_for_print" | xargs -I % sh -c 'echo; cat;'
しかし、動作しません。私はxargsに精通していないので、「-I%sh-c」が正確に何を意味するのかわかりません。誰かが私を助けることができますか?ありがとうございました!
まず、次の間に実質的な違いはありません。
find . | grep "file_for_print" | xargs echo
そして
find . -name "file_for_print*"
ただし、2番目のファイル名はthis_is_not_the_file_for_print
のようなファイル名と一致せず、ファイル名を1行に1つずつ出力します。また、grepがそのほとんどを破棄するためだけに、再帰的なディレクトリ構造全体を生成して印刷する必要がないため、はるかに高速になります。
find . -name "file_for_print*"
実際にはまったく同じです
find . -name "file_for_print*" -print
ここで、-print
アクションは、一致した各ファイル名の後に改行を出力します。 find
にアクションを指定しない場合は、-print
が必要であると見なされます。しかし、それよりも多くのトリックがあります。例えば:
find . -name "file_for_print*" -exec cat {} \;
-exec
アクションにより、findは\;
まで次のコマンドを実行し、{}
を一致する各ファイル名に置き換えます。
find
は、それ自体を単一のアクションに制限しません。あなたはそれをあなたが望む多くのことをするように言うことができます。そう:
find . -name "file_for_print*" -print -exec cat {} \;
おそらくあなたが望むものはかなりうまくいくでしょう。
この非常に便利なユーティリティの詳細については、次のように入力してください。
man find
または
info find
そしてそれについてすべて読んでください。
find . | grep "file_for_print" | xargs -I % sh -c 'echo %; cat %;'
(OPがありませんでした%
s)
まだ言われていないので:-I %
はxargsに '%'をあなたが与えたコマンドの引数に置き換えるように指示します。 sh -c '...'
は、新しいシェルでコマンド'...'
を実行することを意味します。
そう
xargs -I % sh -c 'echo %; cat %;'
xargs
に指定されたすべてのファイル名に対して、echo [filename]
の後にcat [filename]
が実行されます。 echoコマンドとcatコマンドは、別のシェルプロセス内で実行されますが、これは通常は問題ではありません。 xargs
に渡されたコマンド内に%
記号がないため、バージョンは機能しませんでした。
同じことを達成するために、このコマンドを使用する価値があります。
find -name "*file_for_print*" | parallel 'echo {}; cat {};'
単純だからです(parallel
は自動的に{}
を置換文字として使用し、デフォルトで複数のコマンドを受け取ることができます)。
この特定のケースでは、とにかく各コマンドは個々のファイルごとに実行されるため、xargsを使用する利点はありません。 'find'に-execを2回追加するだけです。
find . -name "*file_for_print*" -exec echo {} \; -exec cat {} \;
この場合、riciが指摘する最初のecho
の代わりに-print
を使用できますが、この例は、単一のfind
で2つの任意のコマンドを実行する機能を示しています。
独自のbash関数を作成するのはどうですか?
#!/bin/bash
myFunction() {
while read -r file; do
echo "$file"
cat "$file"
done
}
find . -name "file_for_print*" | myFunction