複数行の正規表現に一致するファイルを検索します(pcregrepを使用しません)

複数行の正規表現に一致するファイルを検索します(pcregrepを使用しません)

質問:

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現在の行番号を印刷します。行番号出力はファイルの行番号です。=sedLine

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に達すると、ラインカウンタ($.)がリセットされます。

関連情報