繰り返しパターンを検索し、一致する各項目の特定のシーケンス(行番号、ファイル名、ファイル内容なし)を印刷します。

繰り返しパターンを検索し、一致する各項目の特定のシーケンス(行番号、ファイル名、ファイル内容なし)を印刷します。

私が望むのはこことほぼ同じですが、結果の形式を「行番号、区切り文字、ファイル名、改行」と指定して、行番号がファイル名の後ろではなく行の先頭に表示されるようにしたいと思います。一致する項目を含む行は表示されません。

この形式が好ましい理由は次のとおりです。

  • (ㅏ)ファイル名は長くて秘密にすることができ、ツールがファイル名を行番号と区切るために使用する区切り文字を含みます。これは、ファイル内のパターンにも同じ区切り文字を含めることができるため、awkでこれを行うのは非常に困難です。また、行の先頭の行番号は、ファイル名の後に表示される行番号よりも整列しています。この必須形式が必要な別の理由は、
  • (二)パターンに一致する行が長すぎるため、stdoutに示されている出力から1行あたり1行の属性を混乱させることができます。ファイルに保存し、次のツールを使用するよりもstdoutで出力を表示する方が良いでしょう。 viを使用すると、出力ファイルの各行を1行ずつ表示できます。

    ディレクトリからパターンを再帰的に検索し、ファイル名と行番号のみを印刷する方法

これでリクエストを行ったので、次の点を考慮してください。

  1. 私が使用しているLinuxホストにAckがインストールされていないため、使用できません。

  2. 次の操作を行うと、シェルはfind ."find ." を実行し、現在の作業ディレクトリから開始し、再帰的に降りる絶対パスのリストに置き換えます。

    grep -n PATTERN $(find .)
    

    その後、-n は行番号を印刷しますが、目的の場所は印刷しません。また、何らかの理由でディレクトリ名にパターンが含まれていると、grepがそのパターンを含む通常のファイルと一致するかどうかはわかりません。これは私が望むものではないので、次を使用します。

    grep -n PATTERN $(find . -type f)
    

    また、 find 出力が grep に動的に渡されるように、このコマンドを変更したいと思います。まず、絶対パスの完全なリストを作成してから、ほとんどをgrepに渡すのではなく、リストを作成するときに各行をgrepに渡したほうがよいので、次のことを試しました。

    find . -exec grep -n PATTERN  '{}' \;
    

    によると、これは正しい構文であるようですが、man pageこのコマンドを実行するとBashシェルが約100倍遅く実行されるため、これは正しいアプローチではありません。

私が説明した内容を考えると、どのようにこのコマンドと同様の操作を行い、必要な形式を取得できますか?問題の投稿に関する質問をリストしました。

ベストアンサー1

grepを使う

を使用する代わりにファイルシステムの反復に-r切り替えることができないのはなぜですか?私はまた、スイッチの代わりに2つの追加のスイッチを使用します。grepfind-n

$ grep -rHn PATTERN <DIR> | cut -d":" -f1-2

例 #1

$ grep -rHn PATH ~/.bashrc | cut -d":" -f1-2
/home/saml/.bashrc:25

詳細

  • -r- ファイル+ディレクトリを再帰的に検索
  • -H- 一致する場合はファイル名を印刷します(より制限が少ない)。つまり、他のスイッチと一緒に-l使用されます。grep
  • -n- 一致する行番号を表示

例 #2

$ grep -rHn PATH ~/.bash* | cut -d":" -f1-2
/home/saml/.bash_profile:10
/home/saml/.bash_profile:12
/home/saml/.bash_profile_askapache:99
/home/saml/.bash_profile_askapache:101
/home/saml/.bash_profile_askapache:118
/home/saml/.bash_profile_askapache:166
/home/saml/.bash_profile_askapache:218
/home/saml/.bash_profile_askapache:250
/home/saml/.bash_profile_askapache:314
/home/saml/.bash_profile_askapache:2317
/home/saml/.bash_profile_askapache:2323
/home/saml/.bashrc:25

検索の使用

$ find . -exec sh -c 'grep -Hn PATTERN "$@" | cut -d":" -f1-2' {}  +

はい

$ find ~/.bash* -exec sh -c 'grep -Hn PATH "$@" | cut -d":" -f1-2' {}  +
/home/saml/.bash_profile:10
/home/saml/.bash_profile:12
/home/saml/.bash_profile_askapache:99
/home/saml/.bash_profile_askapache:101
/home/saml/.bash_profile_askapache:118
/home/saml/.bash_profile_askapache:166
/home/saml/.bash_profile_askapache:218
/home/saml/.bash_profile_askapache:250
/home/saml/.bash_profile_askapache:314
/home/saml/.bash_profile_askapache:2317
/home/saml/.bash_profile_askapache:2323
/home/saml/.bashrc:25

本当に使用したい場合は、.findファイルを使用してファイルを見つけて、これを行うことがfindできます。grepfind

おすすめ記事