1行に複数の一致をgrep / awk / sedして、それ以降の情報を取得できますか?

1行に複数の一致をgrep / awk / sedして、それ以降の情報を取得できますか?

私が受け取ったファイルは外部ソースから取得されたもので、ファイルは整理されていません...興味のある情報も含まれており、興味のない情報も含まれています。

name: myName var1: xxx var2: bbbb
var1: xxx var2: aaaa name: myName
name: myName var1: yyy var2: bbbb
var1: xxx var2: aaaa name: myName
name: myName var1: yyy var2: aaaa
var2: aaaa name: myName var1: xxx 
name: myName var1: zzz var2: bbbb
var2: aaaa name: myName var1: zzz

私が出力したいのはvar1andに関連する値だけなのでvar2ソートされたのでこれがvar1最初のものです。このように:

xxx bbbb
xxx aaaa
yyy bbbb
xxx aaaa
yyy aaaa
xxx aaaa
zzz bbbb
zzz aaaa

これが可能であれば、どんなアイデアがありますか?

答え1

あなたはこれを行うことができますawk

awk '{
        v1 = v2 = ""
        for (i=1; i<NF; i+=2) {
                if ($i == "var1:") v1 = $(i+1)
                if ($i == "var2:") v2 = $(i+1)
        }
        print v1, v2
     }'

各行に対してすべての奇数フィールド($1、、$3および)をテストしてorであること  $5を確認し、一致する場合は、値(次のフィールド、から、またはまで)をorにコピーします。var1:var2:$(i+1)$2$4$6v1v2

答え2

Perlは、キーと値のペアでハッシュを作成します。

$ perl -alnE 'my %h = @F; say "$h{qw(var1:)} $h{qw(var2:)}"' file
xxx bbbb
xxx aaaa
yyy bbbb
xxx aaaa
yyy aaaa
xxx aaaa
zzz bbbb
zzz aaaa

答え3

いくつかの方法でこれを行うことができます。そのうちの2つは次のとおりです。

$ perl -lne 'print /(?=.*var1:\h+(\H+))(?=.*var2:(\h+\H+))/' input.file


$ sed -e '
     H;s/.*//;x
     s/.*[[:space:]]var2: \([^[:space:]]\{1,\}\)/\1 &/
     s/.*[[:space:]]var1: \([^[:space:]]\{1,\}\)/\1 &/
     s/ \n.*//
' input.file

の機能を使用すると、GNU sed次のように多くの作業を簡素化できます。

$ sed -Ee ' 
    s/^/\n/
    s/.*\svar2: (\S+)/\1 &/
    s/.*\svar1: (\S+)/\1 &/
    s/ \n.*//
' input.file

出力:

xxx bbbb
xxx aaaa
yyy bbbb
xxx aaaa
yyy aaaa
xxx aaaa
zzz bbbb
zzz aaaa

答え4

datのデータにはgnu sedを使用してください。

$ sed -E 's/.*var1:\s(\S+).+var2:\s(\S+).*|.*var2:\s(\S+).+var1:\s(\S+).*/\1\4 \2\3/' dat

関連情報