UNIXの場合:フォルダには、拡張子が.sas
(プログラム)のファイルと.sas7bdat
(テーブル)のファイルがあります。 「liasse」というテキストを含むプログラム(テーブルではない)を見つける必要があります。このコマンドを起動してみました:
grep -rli liasse *.sas ./
その結果、テーブル名が表示されます。プログラムのみを取得するコマンドはどうあるべきですか?
これは、POSIX準拠のコマンドであり、一度に多くのファイルに対してgrep
を起動します。
find . -type f -name '*.sas' -exec grep -li liasse {} +
find
のマニュアルページgrep
のマニュアルページコマンドgrep -rli liasse *.sas ./
が期待どおりに機能しません。何が起こるかを分析しましょう:
*.sas
はシェルグロブを受けます。*.sas
に一致するオブジェクトが少なくとも1つある場合、それらはすべてliasse
の後に配置されます。grep
は、検査対象のパスとしてリテラル*.sas
を取得し(状況によって異なります。たとえば、bash
のshopt -s nullglob
、shopt -s failglob
を調査します)、警告をスローする場合があります。grep
は./
を取得し、ファイル内のliasse
の検索でそれを再帰的に処理します。これにより、./
の下にあるすべてのファイルが処理されます:プログラム、テーブルなど。そのため、結果にテーブル名を含めることができます。
私のコマンドfind . -type f -name '*.sas' -exec grep -li liasse {} +
は、*.sas
パターンに一致するファイルに対してのみgrep
を実行します。重要な事柄:
-type f
はファイルのみを選択します。このようにして、ディレクトリ名が*.sas
(存在する場合)と一致することがgrep
に渡されないようにします(-r
なしのgrep
はとにかくそれらを拒否する必要がありますが、エレガントではありません) 。find
は、*.sas
オペランドの引数としてリテラル-name
を取得します。このようなパターンを解釈する方法を知っています。find … -exec … {} +
構文は、{}
の代わりに複数のオブジェクトを置き換えます。このようにして、find … -exec … {} \;
と比較して、作成されるgrep
プロセスが少なくなります(おそらく1つだけ)。find
コマンドを使用して、名前ですべてのファイルを再帰的に検索し、各ファイルに対してgrep
を実行できます。最も簡単な解決策は、findの-exec
オプションを使用することです。
find . -name '*.sas' -exec grep -li liasse {} \;
または、find
とxargs
を組み合わせることができます。
find . -name '*.sas' -print0 | xargs -0 grep -li liasse
これは、すべての単一ファイルではなく、ファイルの大きなバッチに対してgrep
を実行するため、パフォーマンスがわずかに向上します。
xargs
の-P
オプションを使用すると、複数のgrep呼び出しを並行して実行することもできます。