awkにファイルテキスト内の一致する文字列の複数行を条件付きで印刷させるにはどうすればよいですか?

awkにファイルテキスト内の一致する文字列の複数行を条件付きで印刷させるにはどうすればよいですか?

条件に合った複数のパターンの行を印刷するには?

たとえば、入力ファイルの場合

セクションには以下が含まれます。

ID : 1

Status : Ok

Name : Lulu

Age : 18

State : US




ID : 2

Status : Ok

Name : Master Yi

Age : 22

State : UK



ID : 3

Status : Ok

Name : Garen

Age : 20

State : CA
------------

Codition : IF Age == 20 | print 
----------

ID : 3

Status : Ok

Name : Garen

Age : 20

State : CA

助けてください

ありがとう

答え1

ファイルが表示されているように見える場合は、各レコード間に4つの空白行があり、各レコード間に3つの空白行がある場合は、次のことができます。

$ awk -v RS='\n\n\n\n' '/Age : 20\n/' file 
ID : 3

Status : Ok

Name : Garen

Age : 20

State : CA

あなたはこれを明確にしませんでしたが、余分な空白行は実際にはファイルの一部ではなく問題の書式のアーティファクトにすぎないと思います。したがって、レコードの各行の間には空行が 1 つだけあり、レコードごとのレコード間に 2 つの空行があります。その場合、入力ファイルは次のようになります。

ID : 1
Status : Ok
Name : Lulu
Age : 18
State : US


ID : 2
Status : Ok
Name : Master Yi
Age : 22
State : UK

ID : 3
Status : Ok
Name : Garen
Age : 20
State : CA

ファイルが次のような場合は、次のようにできます。

$ awk -v RS= '/Age : 20\n/' file
ID : 3
Status : Ok
Name : Garen
Age : 20
State : CA

答え2

次の方法では、最初にフィールドのラベル(名前)をその値にマッピングする配列を作成し、今すぐ必要な操作を実行し、後で複合条件をテストし、選択フィールドを印刷し、フィールドを異なる順序で印刷するように簡単に拡張できます。あります。または、タイプデータに対して別の操作を実行しますtag:value

$ cat tst.awk
BEGIN { OFS=" : " }
!NF { next }
{
    tag = val = $0
    sub(/ *:.*/,"",tag)
    sub(/[^:]+ *: */,"",val)
    if ( !(tag in tag2val) ) {
        tags[++numTags] = tag
    }
    tag2val[tag] = val
}
tag == "State" {
    if ( tag2val["Age"] == 20 ) {
        for (tagNr=1; tagNr<=numTags; tagNr++) {
            tag = tags[tagNr]
            val = tag2val[tag]
            print tag, val
        }
        print ""
    }
    delete tag2val
    numTags = 0
}

$ awk -f tst.awk file
ID : 3
Status : Ok
Name : Garen
Age : 20
State : CA

関連情報