Bash:ファイルのディレクトリで特定の文字列を検索する方法はありますか?[複製]


47

可能性の重複:
Linuxでのテキストパターンを検索します

bashでは、探している特定の文字列が現在のディレクトリにあるファイル内に存在するかどうかを知らせるコマンドがあるかどうか疑問に思っていました。

現在のディレクトリの一連のCファイル内で関数 'toUpperCase()'を探しているとします。多くのファイルがあるので、vimを使用して各ファイルを手動で開き、文字列 'toUpperCase'を確認するのは時間がかかります。bashコマンドラインではない場合、これを効率的に行う別の方法はありますか?

回答:


64

grep

grep -R "toUppercase()" *

または、ack-grepがインストールされている場合、単純に:

ack-grep "toUppercase"

Cファイルでの検索を制限する場合は、次を使用しますack-grep

ack-grep -cc "toUppercase()"

ack-grepOSXにインストールすることもできますが、実行可能ファイルの名前はjust ackです。


あまりにも多くのことで、SOにはすでに疑わしい類似の質問があります;)
デビッドペリー

10

標準のテキスト検索ツールはgrepです。

現在のディレクトリtoUpperCase(内のすべての.cファイルで文字列を検索するには:

grep -F 'toUpperCase(' *.c

サブディレクトリも調べたい場合:

grep -r --include='*.c' -F 'toUpperCase('

C関数呼び出しを探している場合は、ctagsの方が適している可能性があります。すべてのソースファイルで1回実行して識別子のインデックスを作成し、エディターを使用して呼び出し間を移動します。すべてのviライクなエディターはctagsのTAGSファイルを使用できます。Emacsを使用している場合、同様のプログラムを実行しetagsます。


ctags関数呼び出しではなく関数定義を見つけるのに便利です。
JdeBP

6

vimを使用しています。これを行うためのツールが組み込まれています。

予想通り、既に使用するように言っている7つの答えがありますgrep。しかし、あなたがあなたの質問からあなたが使用していることに気づいた唯一の人であるようですvim。そのため、内から使用できます、の組み込みツール使用できます。これはコマンドを介して呼び出されます。 grepvimvim:vimgrep

「関数の呼び出しのために、現在のディレクトリにCソースファイルのすべてを検索するにはtoUpperCase()1種類の」vimコマンド

:vimgrep "\<toUpperCase\_s*(" *.c

結果の一致リストは、quickfixリストに自動的にロードされ、次のいずれかでアクセスできます(微妙な違いについてはオンラインヘルプを参照してください)

:copen
:cwin

関数の定義を見つけるのctagsは、それを呼び出すのではなく、ツールであり、Gillesの回答で述べたように、:tjumpor :tselectコマンドと組み合わせて使用します。

なぜ使用:vimgrep

オンラインヘルプ(:help grep)にはいくつかの理由が列挙されていますが、ここでは説明しません。さらに、これらに、行動の比較:vimgrepのそれとdietbuddhaの答えがdietbuddhaのコマンドラインgrepは、個々のCソースファイルごとに個別のプロセスをフォークします。xargsそのオーバーヘッドを削減するためにも使用していません。また、出力が終了したら、何らかの方法で出力を解析して、関連するソースファイルでテキストエディターを呼び出す必要があります。 :vimgrep複数の追加プロセスを分岐させないため、結果を使用すること自体が単純です。結果のクイックフィックスリストのエントリの1つを選択するだけで、関連するソースファイルの関連する行にカーソルが自動的に配置されます。

実際、それはあなたが書いたのとまったく同じことをしますが、自動的に行われます。これは、まさにテキストエディターのアクションを自動化する方法です。手動でロードされたかのようにファイルをロードし、正規表現を検索し(既に他の場所で使用しているのと同じ正規表現構文を使用vim)、一致する場所を記録してからファイルをアンロードします。


2

はい、ツールはと呼ばれgrepます。

grepコマンドは、指定されたパターンに一致する行を含む1つ以上の入力ファイルを検索します。デフォルトでは、grepは一致する行を出力します。

基本的な使用法は次のとおりです。

grep something somewhere

または、より具体的に:

grep [some options] pattern file

非常に単純なケースでは、すべてのファイルを再帰的に検索するため、-rオプションを指定します。大文字でも小文字でもかまわない場合は、-iオプションで大文字と小文字を区別しないようにします。

grep -ri "touppercase()" .

一致する部分のみが必要な場合は、-oオプションを使用します。

Grepは正規表現を使用でき、巨大なマニュアルがあります


2

grep標準の答えです-再帰的かと一緒に検索するか-rフラグを使用してfind(例えば、このサイト上の他の質問での議論と例、この1

最近の私の好みの選択はackです。コンピュータにインストールされる可能性は低いですが、Ubuntuでapt-getを使用してインストールするか、単にダウンロードすることができます。リンク、手順、およびgrepよりも優れている理由は、http://betterthangrep.com/で入手できます。


1

find そして grep

find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print

なぜだけじゃないのgrep

grep -r string .現在のディレクトリ内のすべてのファイルを再帰処理します。オブジェクトファイルまたはその他のバイナリがある場合は、バイナリ結果とも一致するものが返されることがあります。ジャンク。また、サブディレクトリにfifoまたはデバイスファイルが含まれている場合は、不明または意図しない結果が生じる可能性があります。

grep string *.c現在のディレクトリ.cファイルのみを検索します。

grep string **/*.c すべてのサブディレクトリを検索します。ただし、非常に多数の.cファイルがある場合は、シェルグロブの拡張の最大数を超えるリスクがあります。また、拡張は最初に発生する必要がありgrepます。つまり、開始前に完全なツリートラバースが行われます。


0

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

3
grepには、これを行う-Hオプションがあります。grepの-Hnどんな*
ロイ・リコ

毎日新しいことを学んでください。ありがとうございます。@ Roy Rico
Tim Brigham

0

「特定の文字列が現在のディレクトリにあるファイル内に存在するかどうかを確認するにはどうすればよいですか」という特定の質問に誰も回答していないのは興味深いことです。私の知る限り、ファイルのグループで一致が見つかったかどうかのみを返す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"

ファイル拡張子の2番目の引数を問題なく受け入れることで、このシェルスクリプトをより一般的にすることができます。

ダグ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.