ソースファイルを見ています。実際にはPureBasicの場合ですが、言語に関係なく共通の要素があります。私の場合は、カバー拡張と次pb
のコマンドを使用します。pbi
pbf
pbp
find . -name "*.pb*" -exec grep -Hnr ... \;
問題はこれが原因ですfull/path/filename.ext:ln#:contents of that line
。
2つのうちの1つを実行したいと思います。パスを完全に切り取って(/
最初のパスの前の最後のパス:
)、残します。
filename.ext:ln#:contents of that line
または、区切り線を使用して次の操作を行います。
full/path/filename.ext:
ln#:contents of that line
どちらにしても結果を読みやすくします。次の場所に分割することもできます。
full/path/filename.ext:ln#:
contents of that line
読みやすさを高めるため。私は柔軟です。それはそれらの一つかもしれません。 1行のコマンドやこれらの特定のコマンドに限定される必要はありません。
find
を含むgrep
私が見つけることができるすべてのリストされたスキルを試しましたが、sed
必要に応じて組み合わせを実装することはできません。
答え1
あなたの説明によると、これを行うようです(水平スクロールを避けるために4行に分割しました)。
>tmp.txt;
find . -type f -name "*.pb*" \
-exec grep -Hn pattern "{}" ";" >>tmp.txt;
cat tmp.txt | more
-execdir
Gnu findを使用している場合は;を代わりに使用できます。-exec
これにより、コマンドがターゲットファイルのディレクトリで実行され、そのgrep
結果、ファイル名はそのディレクトリに相対的になります。 (今すぐ./filename.ext
)。それじゃないかなり要求された内容ですがかなり近く、使用する必要がある他の理由もあります-execdir
。
-execdir grep -Hn pattern "{}" ";" # See note 1
別のオプションは、中間シェルを使用してファイル名タグを編集することです。これにはGnugrep
オプションが必要です--label
。
-exec bash -c 'grep -Hn --label="$(basename "$1")" pattern "$1"' \
_ "{}" ";"
これはオペレーティングシステムに対してかなり長く、より多くの作業を実行しますが./
。
sed
2番目のオプションでは、各行の最初(または2番目)行の後に改行文字を挿入して出力全体をパイプすることができます:
。
find . -type f -name "*.pb*" \
-exec grep -Hn pattern "{}" ";" |
sed 's/:/&\n/' >>tmp.txt.
または(2番目のコロン):
find . -type f -name "*.pb*" \
-exec grep -Hn pattern "{}" ";" |
sed 's/:[^:]*:/&\n/' >>tmp.txt.
ノート
grepに再帰的に
-r
検索するように指示することは、ディレクトリを引数として提供しないので意味がありません。find
すべてのファイルが再帰的に見つかりました。だから、すべての例からそのオプションを削除しました。cat tmp.txt | more
猫の無駄な使用(UUOC)です。ただ使用してくださいmore tmp.txt
。;
より良い効率のためにGnu findに置き換えられました+
(使用されている例を除くbash -c
)。
答え2
探している前提から始めてください。模様あなたのファイルには、あなたが提案した各レイアウトのソリューションがあります。
パス名の先頭を削除します。
find . -name '*.pb*' -type f -execdir grep -Hn 'PATTERN' {} \; | cut -c3- >tmp.txt more tmp.txt
参照するプログラムを使用するときは
execdir
常にターゲットディレクトリから呼び出され、現在のファイルのパス名は単にパス./
名からcut -c3-
先行を削除することによって。./
パス名で行を分割し、行番号に一致するものに従います。
find . -name '*.pb*' -type f -exec grep -Hn 'PATTERN' {} \; | sed 's/:/:\n/' >tmp.txt
パス名と行番号を使用して行を分割し、一致させます。
find . -name '*.pb*' -type f -exec grep -Hn 'PATTERN' {} \; | sed 's/^\([^:]*:[^:]*:\)/\1\n/' >tmp.txt
ここで
sed
パターンは2番目のコロンで分割されます(REは次のように読み取られます)。行の先頭から始めます。コロンが続くゼロ個以上の非コロン文字と一致します。そしてまた。次に、一致を自分で置き換えてからラップします。)。
ファイル名にコロンまたは改行文字が含まれている場合、これらの回避策のいずれも機能しません。
答え3
awk
代わりに試してみてくださいgrep
。たとえば、デフォルト名のみを印刷します。
find . -name '*.pb*' -exec awk 'function basename(file) {
sub(".*/", "", file)
return file
}
/pattern/{
print basename(FILENAME)":"FNR":"$0
}' {} +
パス/行の内容を分割します。
find . -name '*.pb*' -exec awk '/pattern/{print FILENAME"\n"FNR":"$0}' {} +
または
find . -name '*.pb*' -exec awk '/pattern/{print FILENAME":"FNR":\n"$0}' {} +
grep
ファイル名を一度だけ印刷し、そのファイル内の一致するすべての行を2つのsで印刷したい場合:
find . -name '*.pb*' -exec grep -l pattern {} \; -exec grep -n pattern {} \;
これはすべての種類のファイル名(コロンを含むファイル名を含む)で機能します。
答え4
使用grep -l
find . -type f -exec grep -ilHn --color=always 'searchphrase' {} \;