根据文件 1 中特定模式的位置,基于第一列合并两个文件

根据文件 1 中特定模式的位置,基于第一列合并两个文件

我有以下文件:

文件1(约7000行):

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

文件2(大约30万行):

1010089 26 48 33
1010121 21 62 49

我想根据第一列合并两个文件,具体取决于文件 1 中的 1402-s 位置。例如,如果 1402 在第二列中,我想打印文件 1 的第一列、文件的第二列1和文件2的第二列。如果1402在第三列,我想打印文件1的第一列,文件1的第三列和文件2的第三列。

1402 可以出现在任何列中,而不仅仅是第二或第三列。但是,它不会每行出现一次以上。如果文件 2 中的 $1 不包含文件 1 的 $1,我想打印 $1、1402 和未知。

期望的输出:

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

我使用以下脚本合并两个文件:

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

答案1

如果我知道 file1、file2 和每一列代表什么,我会想出更好的变量名称,但我不那么……在每个 Unix 机器上的任何 shell 中使用任何 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

该解决方案是众多解决方案之一。它非常通用,因此file2即使第一列值重复,它也会处理所有约 300k 行。值“1402”可以放置在 中第一列之后的任何列中file1

华泰

相关内容