段落パターンの「パターンファイル」で複数のパターンを一致させる[閉じる]

段落パターンの「パターンファイル」で複数のパターンを一致させる[閉じる]

入力ファイルがあり、段落内で別の一致を検索し、一致がある場合は、段落全体を含む出力ファイルに移動する必要があります。

1つの重要な点は、出力順序が入力順序を反映する必要があることです。だから段落を検索する必要があります。みんなパターンマッチングファイルのパターン(1行に1つのパターン)、そして一つパターンの一致 該当する段落の追加一致を停止し、一致する段落を出力ファイルに移動し、次の段落に処理をスキップします。

入力ファイル:

DFJKHDKQW
YYYYYYYYYYYY
SDFLKJHSDKLFH

DSFLKHSDLKFH
DFIHERFW
ADFKJH
OIGHRFGH
XXXXXXXXXXXX
SDKFLJH

DFLKHSDFKLH
SDSDJKLFHSDK

OIHGSDFG
AAAAAAAA
LFKHFGJKDGH
KLJHLUG

DFSDKLF
YYYYYYYYYYYY

パターンマッチファイル:

AAAAAAAA
YYYYYYYYYYYY
XXXXXXXXXXXX

予想出力:

DFJKHDKQW
YYYYYYYYYYYY
SDFLKJHSDKLFH

DSFLKHSDLKFH
DFIHERFW
ADFKJH
OIGHRFGH
XXXXXXXXXXXX
SDKFLJH

OIHGSDFG
AAAAAAAA
LFKHFGJKDGH
KLJHLUG

DFSDKLF
YYYYYYYYYYYY

awk私は今想像を超えた一連の問題に直面しています。

  1. 入力ファイルを使用したパターンの一致
  2. 最初に表示されたときに段落を回転し、「次の段落に停止/ジャンプ」
  3. 一致する段落を出力ファイルにコピーします。
  4. 入力から一致する段落を削除します(diff後で2つのファイル間でこれを行うことができるので、オプション)。

答え1

完全な行文字列の一致を実行すると仮定すると、次のものが必要です。

$ cat tst.awk
BEGIN {
    ORS = "\n\n"
    FS = "\n"
}
NR==FNR {
    tgts[$0]
    next
}
{
    out = "unmatched"
    for (i=1; i<=NF; i++) {
        if ($i in tgts) {
            out = "matched"
            break
        }
    }
    print > out
}

$ awk -f tst.awk targets RS= file

$ ls *matched
matched  unmatched

$ head -100 *matched
==> matched <==
DFJKHDKQW
YYYYYYYYYYYY
SDFLKJHSDKLFH

DSFLKHSDLKFH
DFIHERFW
ADFKJH
OIGHRFGH
XXXXXXXXXXXX
SDKFLJH

OIHGSDFG
AAAAAAAA
LFKHFGJKDGH
KLJHLUG

DFSDKLF
YYYYYYYYYYYY


==> unmatched <==
DFLKHSDFKLH
SDSDJKLFHSDK

文字列一致ではなく正規表現を実行する必要がある場合、または正確に一致するのではなく部分を実行する必要がある場合は、別の解決策が必要です(そして、要件をよりよく説明するために質問を更新してください)。

答え2

パターンマッチmatchそれぞれを1つの別々のパターンで入力してください。infile入力してみてください:

awk -F'\n' '!input && !matches[$0]{ next; };
    { for(i=1; i<=NF; i++) {
          if($i in matches) { print sep $0; sep=ORS; break; };
      };
    }' match input=1 RS= infile

またはパターンマッチングmatchパターンブロックを入力してください。infile入力(同じブロックを追加します。match入力infile確認するために)以下を試してください。

awk -v RS= '!input && !matches[$0]{ next; }; ($0 in matches)' match input=1 infile

答え3

短絡モードが既にわかっているので、次のように動作します。まず、「スキーマ」ファイルを解析してから、実際の入力を解析します。出力は通常どおりコンソールに印刷されますが、もちろんファイルにリダイレクトすることもできます。

awk -v ORS="\n\n" 'NR==FNR{pat[++npat]=$0;next}
                   {for (i=1;i<=npat;i++) {if (index($0,pat[i])) {print;next}}}' patterns.txt RS="" input.txt
  • これは、最初に出力レコード区切り文字を2つの改行に設定し、印刷された段落が入力のように空白行に区切られるようにします。

  • 最初のファイルを処理するとき(FNRファイルごとのラインカウンタがNRグローバルラインカウンタと同じ)、すべてのパターンを配列変数に保存するだけですpat

  • 2番目のファイルの場合、レコード区切り文字は空白に設定されており、これはawk「ショートモード」で実行されていることを示します。その後、すべてのパターンを繰り返し、関数を介してindex()入力レコードにそのパターンが見つかったかどうかを明示的に確認します。

ノート

  • この解決策は「部分文字列マッチング」を実行します。言い換えれば、行の1つにある種の「パターン」が見つかった場合、その段落は一致すると見なされます。

  • このindex()機能は、以下を保証するために使用されます。言葉「検索パターン」に正規表現に固有の文字が含まれている場合でも、文字列は一致します。実際に正規表現の一致を使用するには、代わりif ($0 ~ pat[i])にそれを使用してください。

関連情報