2つのシェルコマンドを論理的に結合する方法はありますか?検索 - 実行?
たとえば、すべて印刷してみてください。.csv文字列fooとその発生回数を含むファイルを使用して、次のことをしたいと思います。
find . -iname \*.csv -exec grep foo {} && echo {} \;
しかし、強く打つ「'-exec' 引数の欠落」について文句を言います。
答え1
-exec
シェルではなくコマンドを実行して結果を計算する述語です。本物または間違ったコマンドの結果(0または0以外の終了状態)に基づいています。
だから:
find . -iname '*.csv' -exec grep foo {} \; -print
会議印刷grep
ファイルにfooがある場合のファイルパス。代わりに、別の述語または別の述語を-print
使用できます。-exec
find . -iname '*.csv' -exec grep foo {} \; -exec echo {} \;
負の合計の演算子も参照し!
て見つけてください。-o
または。
または、次のようにシェルを起動できます。
find . -iname '*.csv' -exec sh -c '
grep foo "$1" && echo "$1"' sh {} \;
または、各ファイルに対してシェルを起動しないでください。
find . -iname '*.csv' -exec sh -c '
for file do
grep foo "$file" && echo "$file"
done' sh {} +
答え2
直面する問題は、シェルが最初にコマンドラインを解析し、&&
演算子で区切られた2つの単純なコマンド(find . -iname \*.csv -exec grep foo {}
、、および)を見ることですecho {} \;
。 ()を引用すると&&
これは無視されfind . -iname \*.csv -exec grep foo {} '&&' echo {} \;
ますが、今や引数を使用して同様のfind
コマンドを実行します。この演算子を解釈するシェルを実行するように指示する必要があります。grep
foo
wibble.csv
&&
echo
wibble.csv
find
&&
find . -iname \*.csv -exec sh -c 'grep foo "$0" && echo "$0"' {} \;
sh -c SOMECOMMAND
isの後の最初のパラメータで$0
はありません$1
。
処理を容易にするには、ファイル名を列挙できる-exec … +
ようにいくつかのダミー値を渡します。$0
"$@"
find . -iname \*.csv -exec sh -c 'for x in "$@"; do grep foo "$x" && echo "$x"; done' \ {} +
シェルコマンドが2つのプログラムに分割された2つのプログラムである場合は、&&
これをfind
直接実行できます。 2 つの連続-exec
ジョブを作成し、最初のジョブが状態 0 で終了した場合にのみ、2 番目のジョブを実行します。
find . -iname \*.csv -exec grep foo {} \; -exec echo {} \;
(私は単に説明のためにgrep
andを使用してandに置き換えることができると仮定します。結果出力はとにかく特に有用ではありません。)echo
-exec echo
-print
答え3
この特別な場合には、次のようにします。
find . -iname \*.csv -exec grep -l foo \{\} \;
またはあなたが持っているなら確認する:
ack -al -G '.*\.csv' foo
実際の質問に答えるには、次のようにします。
find . -iname \*.csv -exec sh -c "grep foo {} && echo {}" \;