ファイルで検索文字列を見つけたら、grepコマンドが必要です。行数が不明です。

ファイルで検索文字列を見つけたら、grepコマンドが必要です。行数が不明です。

basefile.txt多くの行の名前の付いたファイルがあります。ファイルのレコードは、コレクションに基づいて論理的にグループ化されます。

たとえば、

"GRP_START","LINE1"........
"A"
"B--BOOM"
"C"
"GRP_START","LINE1"........
"A"
"B--DOOM"
"C"
"D"
"E"
"F"
"G"
"GRP_START","LINE1"........
"E"
"F"
"G"
"C--MOOM"
"GRP_START","LINE1"........

私が望むのは、これらの検索文字列を次keywords.txtのデータを含む別々のファイルに入れることです。

BOOM
DOOM
MOOM

ファイルからテキストを1つずつ読み、keywords.txtそのテキストを検索してbasefile.txt特定のレコードを書き込むコマンドが必要です。finalfile.txt

具体的な記録は次のとおりです。テキスト付きのコレクションを検索する必要があります。

例:上記のファイルから。

このコマンドはBOOMを検索し、次の行を返す必要があります。

"GRP_START","LINE1"........
"A"
"B--BOOM"
"C"

このコマンドはDOOMを検索し、次の行を返す必要があります。

"GRP_START","LINE1"........
"A"
"B--DOOM"
"C"
"D"
"E"
"F"
"G"

したがって、GRP_STARTはグループの開始から次のGRP_STARTまでの記録を記録したいと思いますfinalfile.txt

答え1

次のawkスクリプトはデータファイルを読み取り、各レコードをlines変数に一時的に保存します。word変数のキーワードがレコードに見つかると、do_output変数は1(true)に設定されます。キーワードが見つかり、次のレコードまたはファイルの終わりに達すると、キーワードレコードが出力されます。

#!/usr/bin/awk -f

/^"GRP_START"/ {
    if (do_output) {
        exit;
    }
    lines = $0;
    next;
}

$0 ~ word {
    do_output = 1;
}

{
    lines = sprintf("%s\n%s", lines, $0);
}

END {
    if (do_output) {
        print lines;
    }
}

テストしてみてください:

$ awk -v word="MOOM" -f script.awk basefile.txt
"GRP_START","LINE1"........
"E"
"F"
"G"
"C--MOOM"

その後、必須キーワードを繰り返すだけです。

#!/bin/sh

while read -r word; do
  awk -v word="$word" -f script.awk basefile.txt
done <keywords.txt >finalfile.txt

今後の改善のための提案:まずキーワードを配列に読み込み、basefile.txtデータファイルを一度だけ解析します。

答え2

努力する:

awk 'FNR==NR{re=re (re?"|":"")$0;next} /^"GRP_START"/{if (rec~re)print rec; rec=$0;next} {rec=rec"\n"$0} END{if (rec~re)print rec}' keywords.txt basefile.txt 

例:

$ awk 'FNR==NR{re=re (re?"|":"")$0;next} /^"GRP_START"/{if (rec~re)print rec; rec=$0;next} {rec=rec"\n"$0} END{if (rec~re)print rec}' keywords.txt basefile.txt 
"GRP_START","LINE1"........
"A"
"B--BOOM"
"C"
"GRP_START","LINE1"........
"A"
"B--DOOM"
"C"
"D"
"E"
"F"
"G"
"GRP_START","LINE1"........
"E"
"F"
"G"
"C--MOOM"

どのように動作しますか?

  • FNR==NR{re=re (re?"|":"")$0;next}

    最初のファイルの読み込み中にkeywords.txtすべての単語に一致する正規表現を設定します。たとえば、サンプルデータの場合、re値はBOOM|DOOM|MOOM

  • /^"GRP_START"/{if (rec~re)print rec; rec=$0;next}

    新しいレコードの先頭に達するたびに、最後に保存されたレコードがに保存されている正規表現とrec一致することを確認してくださいre。それでは印刷してみましょう。次に、rec現在の行にリセットするには、残りのコマンドをスキップしてそのnext行に移動します。

  • rec=rec"\n"$0

    他のすべての行の場合はこれをに追加しますrec

  • END{if (rec~re)print rec}

    ファイルを読み取ったら、最終レコードが正規表現と一致することを確認し、一致した場合にre印刷します。

関連情報