固定文字列を含むファイルをgrepしてから、このファイルのみをls -l形式で出力しようとします。
例:
A)次の方法では、複数の-execsを使用してgrepとls -lを出力します。
#
#
# find /usr/bin -type f -exec grep -Eil '#\!\/usr\/bin\/csh' {} \; -exec ls -l {} \; >scripts_csh_list 2>&1
#
#
#
# cat scripts_csh_list
/usr/bin/which
-r-xr-xr-x 1 bin bin 1191 Sep 06 2007 /usr/bin/which
#
#
B)しかし、私たちはls -l ...だけを使い、sh -c 'grep ... {}'で失敗して出力を得るより良い方法が欲しいです。
注:次のコマンドとfind -exec ..の他のすべての組み合わせは次のとおりです。同じ失敗結果を出力します。
#
#
# find /usr/bin -type f -exec sh -c 'grep -Eil '\/usr\/bin\/csh' {} && ls -ltr {}' \; >scripts_csh_list 2>&1t
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
#
# find /usr/bin -type f -exec sh -c ' grep -Eil '\/usr\/bin\/csh' {} ' \; >scripts_csh_list 2>&1
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
# find /usr/bin -type f -exec sh -c ' grep -Eil '\/usr\/bin\/csh' "{}" ' \; >scripts_csh_list 2>&1
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
#
# find /usr/bin -type f -exec sh -c " grep -Eil '\/usr\/bin\/csh' {} " \; >scripts_csh_list 2>&1
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
#
# find /usr/bin -type f -exec sh -c " grep -Eil '\/usr\/bin\/csh' {} " \; >scripts_csh_list 2>&1
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
答え1
原文には不要に見える引用文とたとえ話がたくさんあります。csh
スクリプトはありませんが、次のようにスクリプト/usr/bin
をbash
見つけてls
目的の出力を取得できました。
find /usr/bin -type f -exec grep -q '#!/usr/bin/bash' {} \; -exec ls -l {} \; 2> /dev/null
(2番目のエントリなしで実行してこれを確認しました-exec
。
find /usr/bin -type f -exec grep -q '#!/usr/bin/bash' {} \; 2> /dev/null
結果を確認してください。 )
わずかに異なる出力リストの場合は、次のこともできます。
find /usr/bin -type f -exec grep -q '#!/usr/bin/bash' {} \; -ls 2> /dev/null
一致find
する各ファイル自体を直接計算し、ls
同様の結果を返します。
テスト時に読みやすくするためにエラーをパイプしています/dev/null
。同様の理由で、出力をファイルにパイプしません。
私はbash
シェルを使用しているので、式を一重引用grep
符('...'
)で囲むだけで内容が解釈されるのを防ぐことができます(心配する部分はあまりありません。スラッシュ(/
)はシェルにとって重要ではありません。特別ではありません。他の引用規則YMMVを使用するシェルを使用している場合、少なくともbashには適用されません。
コマンドの場合、その-o
オプションを使用しないとすべての条件が結合されるため、find
コマンドAND
はls -l
スキャンに合格した通常のファイル(含まれているファイル)でのみ実行されます。あなたの質問についてのコメントで指摘したように、あなたが望むことを行うことが可能です。つまり、問題のファイル()が一致していることを確認することです。type f
grep
grep -q
{}
編集:コメントで述べたように、ユーザーのシェルを式からエスケープする必要があるcsh
場合:が機能するはずです。!
grep
'#\!/usr/bin/bash'
答え2
sh -c 'grep ... '
最後に、withコマンドで次の正しい方法を実行しましたfind -exec
。みんなありがとうございます!
# find /usr/bin -type f -exec sh -c ' grep -q ''\#'\!/usr/bin/csh' "$1" && ls -l "$1" ' sh {} \; >scripts_csh_list 2>&1
# head -3 scripts_csh_list
-r-xr-xr-x 1 bin bin 1191 Sep 06 2007 /usr/bin/which