私の問題は、以下が必要だということです。
regex_pattern
指定されたルートディレクトリ内のすべてのファイルで一致するすべての行を検索する(詳細検索)- 一致する行ごとに次のように出力します。
- ファイル名
- 一致する項目を含む行番号
- 行の内容
- 正規表現パターン
- 上記のデータをExcelにインポートします。したがって、CSVまたは区切られた出力形式を念頭に置いてください。
これを行う最も簡単な方法は何ですか?
これについて考えたことを示すために、正規化された単一のファイル名と正規表現パターンを入力として使用し、次のようなおおよそのPerlを使用して行を処理するPerlスクリプトを作成します(まだ試していませんが、最初の試みです):
while (<FILE>) {
$line_number++;
if ($_ =~ m/regex_pattern/) {
# output: file_name\tline_number\tregex_pattern\t$_
# ignore escaping issues for the time being
}
}
再帰検索で各ディレクトリの内容をこのPerlスクリプトに渡す方法はまだわかりません。 Perlで検索することもできますが、Unix / Linuxでこれを行うには良い方法があると確信しています。
私はPerlと結婚しませんでした。標準のUnix / Linuxツールを一緒に接続する方法がある場合は良いでしょう。そうでない場合は、Perlの構文にある程度慣れているので、Perlを使用することをお勧めします。
答え1
このような?
find /search/root -type f -exec awk 'BEGIN{pattern="regex_pattern"} $0 ~ pattern {printf "%s,%s,%s,%s\n",FILENAME,FNR,$0,pattern}' {} +
答え2
start cmd:> find . -type f -name 'search*' -exec awk -v regex=foo \
cont. cmd:> '$0 ~ regex {print FILENAME,FNR,regex,$0 }' {} +
./searchfile1 1 foo a_foo_b
./searchfile2 1 foo foo
答え3
Perl では、以下を使用します。空のファイルハンドルコマンドライン引数に対して機能します。
#!/usr/bin/perl -n
$, = "\t"; # separator added between arguments to print
while (<>) {
if (/regex_pattern/) {
# $ARGV contains the current file name, $. contains the current line number,
# $_ contains the current line including its terminating newline
print $ARGV, $., 'regex_pattern', $_;
}
$. = 0 if eof; # reset the line number between files
}
Perl スクリプトにファイル名を渡すには、ksh93 または bash ≥4 または zsh で以下を使用できます。**
模様サブディレクトリを再帰的に移動します。 kshではまずset -o globstar
。 Bashではshopt -s globstar
。
shopt -s globstar
name_of_perl_script **/*
シェルがそうでない場合、または**
「コマンドラインが長すぎます」エラーが発生した場合に使用できますfind
。
find . -type f -exec name_of_perl_script {} +
より専門的なツールを組み合わせてこれを行うこともできます。ファイルからパターンを検索するgrepを既に知っている可能性があります。この-n
オプションを使用すると、一致する各行の番号が印刷されます。ファイル名に渡すことは、ファイル名も印刷できるようにする方法/dev/null
ですgrep
(コマンドラインに単一のファイルがある場合はこれを行いません)。
grep -n 'regex_pattern' **/*
不足しているのは、必要に応じて区切り文字を変更し(grep
ファイル名、行番号、行内容の間に挿入)、正規表現を正しい場所に挿入することです。:
この簡単な交換は完全に機能しますsed
。正規表現が正しく引用されていることを確認してください。
find . -type f -exec grep -n 'regex_pattern' {} + |
sed 's/^\([^:]*\)\([^:]*\)/\1\t\2\tregex_pattern\t/'