ファイル1の特定のパターン位置に基づいて最初の列に基づいて2つのファイルをマージします。

ファイル1の特定のパターン位置に基づいて最初の列に基づいて2つのファイルをマージします。

次のファイルがあります。

ファイル1(約7000行):

1010089 1402 6814 5543
1010121 6948 1402 2344
1305789 7589 7890 1402
3456889 1254 7389 1256

ファイル2(約300,000行):

1010089 26 48 33
1010121 21 62 49

ファイル1の1402-sの位置に基づいて、最初の列に基づいて2つのファイルをマージしたいと思います。たとえば、2番目の列に1402がある場合は、ファイル1の最初の列、ファイル1の2番目の列、ファイル2の2番目の列を印刷したいとします。 1402が3番目の列にある場合は、ファイル1の最初の列、ファイル1の3番目の列、ファイル2の3番目の列を印刷したいと思います。

1402は、2番目または3番目の列だけでなく、どの列にも表示できます。ただし、1行に複数回表示されるわけではありません。ファイル2の$ 1にファイル1の$ 1が含まれていない場合は、$ 1、1402、および不明を印刷したいと思います。

希望の出力:

1010089 1402 26
1010121 1402 62
1305789 1402 unknown
3456889 0000 unknown

次のスクリプトを使用して2つのファイルをマージします。

awk 'FNR==NR{arr[$1]=$2;next} ($1 in arr){print $0,arr[$1]}' file2 file1

答え1

file1、file2、および各列の意味を知っている場合は、より良い変数名が表示されます。しかし、すべてのUnixシステムのすべてのシェルでawkを使用するわけではありません。

$ cat tst.awk
BEGIN { tgt = 1402 }
NR == FNR {
    file2[$1] = $0
    next
}
{
    fld = "0000"
    val = "unknown"
    for ( i=2; i<=NF; i++ ) {
        if ( $i == tgt ) {
            fld = $i
            if ( $1 in file2 ) {
                split(file2[$1],f)
                val = f[i]
            }
            break
        }
    }
    print $1, fld, val
}

$ awk -f tst.awk file2 file1
1010089 1402 26
1010121 1402 62
1305789 1402 unknown
3456889 0000 unknown

答え2

この試み:

  $ awk 'FNR==NR {for (ii=2;ii<=NF;ii++) if ($ii=="1402") a[$1]=ii;next} 
         {if ($1 in a) {column=a[$1]; print $1,"1402",$column}}' file1 file2
   
  1010089 1402 26
  1010121 1402 62

このソリューションは多くのソリューションの1つです。非常に一般的なので、file2最初の列の値が重複しても、約300,000行をすべて処理します。値「1402」は、の最初の列の後の任意の列に配置できますfile1

ファタイ

関連情報