sh -c 'grep...'で指定された出力形式を取得するためにfind -execコマンドを使用する方法

sh -c 'grep...'で指定された出力形式を取得するためにfind -execコマンドを使用する方法

固定文字列を含むファイルを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/binbash見つけて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コマンドANDls -lスキャンに合格した通常のファイル(含まれているファイル)でのみ実行されます。あなたの質問についてのコメントで指摘したように、あなたが望むことを行うことが可能です。つまり、問題のファイル()が一致していることを確認することです。type fgrepgrep -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

関連情報