2

以下のコードを使用してキーに基づいてマージした2つのファイルがあります

file1
-------------------------------
1      a      t      p      bbb  
2      b      c      f      aaa  
3      d      y      u      bbb  
2      b      c      f      aaa  
2      u      g      t      ccc  
2      b      j      h      ccc

file2
--------------------------------
1   11   bbb  
2   22   ccc  
3   33   aaa  
4   44   aaa  

以下のコードを使用して、これら2つのファイルベースのキーをマージしました

awk 'NR==FNR{a[$3]=$0;next;}{for(x in a){if(x==$5) print $1,$2,$3,$4,a[x]};  

私の質問は、file2の$ 2を変数または配列に保存し、a[x]の後に再度出力する方法です。
私の望む結果は:

1 a t p 1   11  bbb  11  
2 b c f 3   33  aaa  33  
2 b c f 4   44  aaa  44  
3 d y u 1   11  bbb  11  
2 b c f 3   33  aaa  33  
2 b c f 4   44  aaa  44  
2 u g t 2   22  ccc  22  
2 b j h 2   22  ccc  22  

ご覧のとおり、最初の7列はマージコードの結果です。結果に最後の列(a [x]のフィールド2)を追加する必要があります。

重要:

次の質問は、.awkファイルがある場合、(| column -t)のようなbashスクリプトコードを使用したり、結果をファイル(awk... > result.txt)に送信したりするにはどうすればよいですか?私は常にコマンドプロンプトでこれらのコードを使用します。.awkファイルのコード内でそれらを使用できますか?

4

3 に答える 3

3

現在のスクリプトは次のとおりです。

awk 'NR==FNR { a[$3]=$0; next }
             { for (x in a) { if (x==$5) print $1,$2,$3,$4,a[x] } }'

(実際には、オリジナルには2番目のパターン/アクションペアの2番目の閉じ中括弧がありません。)

file2処理する前に処理しているようですfile1

2番目のコードではループは必要ありません。また、最初のフェーズで分割を使用して必要な値を維持することにより、自分の生活を楽にすることができます。

awk 'NR==FNR { c1[$3] = $1; c2[$3] = $2; next }
             { print $1, $2, $3, $4, c1[$5], c2[$5], $5, c2[$5] }'

これをアップグレードして、c1[$5]c2[$5]が定義されているかどうかを確認できます。定義されていない場合は、おそらく行をスキップします。

入力ファイルを指定すると、出力は次のようになります。

1 a t p 1 11 bbb 11
2 b c f 4 44 aaa 44
3 d y u 1 11 bbb 11
2 b c f 4 44 aaa 44
2 u g t 2 22 ccc 22
2 b j h 2 22 ccc 22

列の間隔を与えるか取るか、それが要求されたものです。printf列の間隔は、の代わりにを使用するprintか、OFSをタブに設定するか、または...を使用して固定できます。

列1と2のc1and表記は、2つの列で問題ありません。c2さらに必要な場合は、おそらく2D配列表記を使用する必要があります。

awk 'NR==FNR { for (i = 1; i <= NF; i++) col[i,$3] = $i; next }
             { print $1, $2, $3, $4, col[1,$5], col[2,$5], $5, col[2,$5] }'

これにより、以前と同じ出力が生成されます。

于 2012-10-15T23:16:55.613 に答える
3

file2すべてを配列に追加し、使用splitして必要なビットを保持するだけです。

awk 'FNR==NR { two[$0]++; next } { for (i in two) { split(i, one); if (one[3] == $NF) print $1,$2,$3,$4, i, one[2] } }' file2 file1

結果:

1 a t p 1   11   bbb   11
2 b c f 3   33   aaa   33
2 b c f 4   44   aaa   44
3 d y u 1   11   bbb   11
2 b c f 3   33   aaa   33
2 b c f 4   44   aaa   44
2 u g t 2   22   ccc   22
2 b j h 2   22   ccc   22

あなたの最後の質問について; の中に「パイプ」と「書き込み」を追加することもできますawk。これがへのパイプの例ですcolumn -t

内容script.awk

FNR==NR { 
    two[$0]++
    next
}

{
    for (i in two) {
        split(i, one)
        if (one[3] == $NF) { 
            print $1,$2,$3,$4, i, one[2] | "column -t"
        }
    }
}

次のように実行します:awk -f script.awk file2 file1

編集:

シェルスクリプトに以下を追加します。

results=$(awk '

    FNR==NR {
        two[$0]++
        next
    }

    {
        for (i in two) {
            split(i, one)
            if (one[3] == $NF) {
                print $1,$2,$3,$4, i, one[2] | "column -t"
            }
        }
    }
' $1 $2)

echo "$results"

次のように実行します:

./script.sh file2.txt file1.txt

結果:

1  a  t  p  1  11  bbb  11
2  b  c  f  3  33  aaa  33
2  b  c  f  4  44  aaa  44
3  d  y  u  1  11  bbb  11
2  b  c  f  3  33  aaa  33
2  b  c  f  4  44  aaa  44
2  u  g  t  2  22  ccc  22
2  b  j  h  2  22  ccc  22
于 2012-10-15T23:21:39.670 に答える
2

要求した内容を実現するには、最初のファイルの処理で行全体の後に2番目のフィールドを。で保存しますa[$3]=$0 OFS $2。2番目の質問でawkは、出力のフィールドを区切る変数がありますOFS。これには、タブキーを割り当てて操作します。スクリプトは次のようになります。

awk '
    BEGIN { OFS = "\t"; } 
    NR==FNR{
        a[$3]=$0 OFS $2;
        next;
    }
    {
        for(x in a){
            if(x==$5) print $1,$2,$3,$4,a[x]
        } 
    }
' file2 file1

その結果、次のようになります。

1       a       t       p       1   11   bbb    11
2       b       c       f       4   44   aaa    44
3       d       y       u       1   11   bbb    11
2       b       c       f       4   44   aaa    44
2       u       g       t       2   22   ccc    22                                                                                                                                                                                           
2       b       j       h       2   22   ccc    22
于 2012-10-15T22:30:20.797 に答える