質問:
pcregrepなしでファイル内の複数行の正規表現に一致するエントリをどのように見つけることができますか?
各発生場所を見つけて印刷する必要があります。
残念ながら、pcregrepは存在せず、インストールする権限がありません。他の選択肢などgrep
perl
sed
python
。
検索の正規表現の例は次のとおりです。
Text\nLine
コンテキスト:
1つのスクリプトは何十ものファイルに数百MBの構造化テキストを提供しましたが、残念ながらいくつかの理由でいくつかの行がありませんでした。行がどこにないかを確認して、前の行と次の行の順序を検索する必要があります。
Text
Missing //this line is sometimes missing.
Line
編集する:
可能な入力
はい.txt
Text
Missing
Line
Text
Missing
Line
Text
Line
Text
Missing
Line
可能な出力:
example.txt、10行
失敗した試み:
pcregrep
# command not found
apt-get install pcregrep
# no permission, no su credentials, distro don't provide pcregrep, outdated sources, customer does not want changes on the serve, etc.
sed -r 's#(Text\nLine)#\1#' ./*
# print all lines, not only matches, no indication of file or line, etc.
grep 'Text\nLine' ./*
# Does not works on multi-lines
sed -n '/Text/,/Line/{p}' ./*
# Not the same regex, does not indicate result lines, etc.
答え1
Unixツールは通常行指向であるため、標準ツールボックスを使用して複数行入力に正規表現を適用することはできません。
sed
探している行を検出する方法でファイルを処理することは可能ですが、個々の行に対する作業を厳密に使用してこれを行います。
$ sed -n '/^Text/{N;/^Text\nLine/=;D;}' file
10
このスクリプトは行の先頭で文字列をsed
探します。Text
見つかったら、次の行をバッファに追加し、\n
途中で行を挿入します。
バッファが一致すると、使用中のコマンドは^Text\nLine
現在の行番号を印刷します。行番号出力はファイルの行番号です。=
sed
Line
2番目の正規表現はファイルの改行文字と一致するようですが、そうではありません。これは内部バッファの改行文字と一致し、N
ファイルから次の行を読み取るときにコマンドを使用してその行に入れます。
複数のファイルに適用するには、ループで使用できます。
for name in pattern; do
printf 'Processing %s...\n' "$name"
sed -n '/^Text/{N;/^Text\nLine/=;D;}' "$name"
done
pattern
興味のあるファイルと一致する一般的なファイル名ワイルドカードパターンはどこにありますか?
答え2
インストールした場合は、次のモードで使用vim
できます。ex
vim -e -s -c 'argdo g/^Text\nLine/#' -c q ./*.txt
状況に応じたコマンドも参照してくださいz
。
vim -e -s -c 'argdo g/^Text\nLine/z#.5' -c q ./*.txt
ただし、これはファイル名を印刷しません。より効率の低いperl
アプローチは次のとおりです。
perl -l -0777 -ne 'while (/Text\nLine/g) {
print "$ARGV, line " . ++(() = $` =~ /\n/g)}' ./*.txt
答え3
perl -ne 'eof and $. = 0 or /^Text/ && ($_ .= <>) =~ /^Line/m && print "$ARGV: $.\n"' ./*
これにより、一致が発生したファイル名と行番号が印刷されます。
また、各ファイルのeofに達すると、ラインカウンタ($.)がリセットされます。