可能な重複:
linuxでテキストパターンを検索します
Bashでは、探している特定の文字列が現在のディレクトリにあるファイル内に存在するかどうかを知らせるコマンドがあるかどうか疑問に思いました。
現在のディレクトリのCファイルのセット内で関数 'toUpperCase()'を探しているとします。たくさんのファイルがあるので、vimを使って手動でそれぞれを開き、文字列 'toUpperCase'をチェックするのは時間がかかるのでしたくないでしょう。 bashコマンドラインではない場合、これを効率的に実行する別の方法はありますか?
grep
の場合:
grep -R "toUppercase()" *
あるいは、 ack-grep がインストールされているのなら、単に:
ack-grep "toUppercase"
ack-grep
を使用して、Cファイル内の検索を制限したい場合は、
ack-grep -cc "toUppercase()"
ack-grep
はOSXにもインストールできますが、実行ファイルは単にack
と呼ばれます。
標準のテキスト検索ツールは grep です。
現在のディレクトリ内のすべてのtoUpperCase(
ファイルで文字列.c
を探すには、次のようにします。
grep -F 'toUpperCase(' *.c
サブディレクトリも調べたい場合は、
grep -r --include='*.c' -F 'toUpperCase('
Cの関数呼び出しを探しているなら、 ctags が適しています。すべてのソースファイルに対して1回実行して識別子のインデックスを作成し、次にエディタを使用して呼び出し間を移動します。すべてのvi風エディタはctagsのTAGS
ファイルを使用できます。 Emacsを使用している場合は、同様のプログラムetags
を実行してください。
予想通り、grep
を使用するように言っている7つの答えがあります。しかし、あなたがあなたの質問からvim
を使用していることに気づいたのは、これまでのところ私だけです。そのため、cangrep
内からvim
を使用しますが、alsovim
の組み込みツールを使用できます。これは:vimgrep
コマンドを介して呼び出されます。
「現在のディレクトリにあるすべてのCソースファイルから関数toUpperCase()
への呼び出しを検索するには」vim
コマンドを入力します。
:vimgrep "\<toUpperCase\_s*(" *.c
結果の一致リストは、quickfixリストに自動的にロードされ、次のいずれかでアクセスできます(微妙な違いについてはオンラインヘルプを参照してください)
:copen
:cwin
関数を見つけるためにdefinitionを呼び出すのではなく、ctags
がツールです。 Gilles
のanswer で説明されているように、:tjump
または:tselect
コマンドと組み合わせて。
:vimgrep
を使用する理由オンラインヘルプ(:help grep
)にはいくつかの理由がありますが、ここでは説明しません。さらに、:vimgrep
のアクションを dietbuddha
のanswer のアクションと比較します。 dietbuddha
のコマンドラインは、個々のCソースファイルごとに個々のgrep
プロセスをフォークします。そのオーバーヘッドを削減するためにxargs
も使用していません。そして、出力が終了したら、何らかの方法で出力を解析して、関連するソースファイルでテキストエディターを呼び出す必要があります。 :vimgrep
は複数の追加プロセスを分岐しません。結果を使用すること自体が単純です。結果のクイックフィックスリストのエントリの1つを選択するだけで、関連するソースファイルの関連する行にカーソルが自動的に配置されます。
実際、それはあなたが書いたものをあなたが手で行うことを正確に行いますが、自動的に行われます。これは、テキストエディターのアクションを自動化する方法です。手動でロードされたかのようにファイルをロードし、正規表現を検索し(vim
の別の場所で既に使用しているsame正規表現構文を使用)、一致する場所を記録します。ファイルをアンロードします。
はい、ツールは grep
と呼ばれます。
Grepコマンドは、指定されたパターンに一致する行を含む1つ以上の入力ファイルを検索します。デフォルトでは、grepは一致する行を表示します。
基本的な使い方は:
grep something somewhere
具体的には、
grep [some options] pattern file
非常に単純なケースでは、すべてのファイルを再帰的に検索したいので、-r
オプションを指定します。大文字と小文字を区別しない場合は、-i
オプションを使用して大文字と小文字を区別しないようにしてください。
grep -ri "touppercase()" .
一致する部分だけが必要な場合は、-o
オプションを使用してください。
grep
が標準的な答えです。再帰的に、またはfind
と組み合わせて-rフラグを使用する( this one のように、このサイトの他の質問の説明と例)
最近の私の選択はack
です。おそらくあなたのコンピュータにインストールされているわけではありませんが、Ubuntuのapt-getを使ってインストールすることも、単にダウンロードすることもできます。リンク、手順、およびgrepより優れている理由は、 http://betterthangrep.com/ で入手できます。
find
とgrep
find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print
なぜgrep
だけではないのですか?
grep -r string .
は、現在のディレクトリ内のすべてのファイルを再帰的に処理します。もしあなたがオブジェクトファイルや他のバイナリを持っているのなら、バイナリの結果(別名)と一致するかもしれません。ジャンク。あなたがサブディレクトリにfifosやデバイスファイルを持っているのであれば、あなたは未知の/意図しない結果を招く可能性があります。
grep string *.c
は現在のディレクトリの.c
ファイルのみを検索します。
grep string **/*.c
はすべてのサブディレクトリを検索します。しかし、非常に多数の.c
ファイルがある場合、Shell globの最大拡張数を超える危険性があります。展開も最初に行わなければならず、それはgrep
が始まる前に完全な木のトラバースを意味します。
Grepはうまくいくでしょうが、ファイルの名前と参照されている正確な行を見つけるために、もう少しスクリプトを追加することをお勧めします。それがあなたが望むものであるならば、私は以下がうまくいくと思います。シェルスクリプトとして保存しておき、最初のコマンドラインオプションとして必要な値を渡します。
for i in $(ls)
do
cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
STATUS=$?
if [ $STATUS -eq 0 ] ; then
echo $i
cat $i | grep -n $1
fi
done
「現在のディレクトリにあるファイル内に特定の文字列が存在するかどうかはどうすればわかりますか」という特定の質問に誰も答えていないのは興味深いことです。私が知っている限りでは、ファイルグループ内で一致が見つかったかどうかだけを返すgrepオプションはありません。最も近いオプションは、ファイル名を一覧表示するための-lです。これまでのところ最も近い答えはtimからのもので、若干の微調整があります。
#!/usr/bin/bash
for i in $(ls *.c 2> /dev/null)
do
cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
STATUS=$?
if [ $STATUS -eq 0 ] ; then
echo "Found"
exit
fi
done
echo "Not found"
あなたは、あまり問題なくファイル拡張子のための第二引数を受け入れることによって、このシェルスクリプトをより一般的にすることができます。
ダグ