通过行号交叉引用两个文件中的字符串,并将它们收集到第三个文件中

时间:2018-12-14 18:00:27

标签: bash shell awk

我有两个文件,希望将它们协调成一个用于绘制xy图的文件。

File1每行包含一个不同的x值,然后在同一行上包含一系列y值。 File2包含每个点x我从File1需要的特定y值。

实际上,我有50,000行和50-100列,但这是一个简化的示例。

File1如下所示:

 1 15 2 3 1
 2 18 4 6 5
 3 19 7 8 9
 4 23 10 2 11
 5 25 18 17 16 
  • 第1列是行号。
  • 第2列是我的x值,以升序排序。
  • 第3-5列是我的y值。它们不是唯一的。一行上的y可以匹配另一行上的y。

File2如下所示:

 3
 5
 2
 18

File2中每一行的y对应于与同一行中File1的y之一匹配的数字(对于前几百行)。前几百行之后,它们可能并不总是匹配。因此,File2的行少于File1的行。我想忽略这些行或将其填充为0。

目标

输出File3应该包含:

 15 3
 18 5
 19 0
 23 2
 25 18

或带有

的行
 19 0   

已删除,以适用于该脚本的为准。如果这两种选择都不可行,那么我也可以逐行匹配y值,直到没有匹配项,然后再停止。

尝试

我最初将File2路由到一个数组中:

  a=( $(grep -e '14,12|:*' File0 | cut -b 9-17) )

但是随后我注意到Stackexchange上的类似问题(12)使用了第二个文件,因此我将上述grep命令路由到了File2中。

这些问题稍有不同,因为我需要File1中的特定列,但是我认为我至少可以将它们用作起点。这些问题的解决方案:

1)

        grep -Fwf File2 File1

当然会复制File1的整个行,我不确定如何从那里继续。或

2)

  awk 'FNR==NR {arr[$1];next} $1 in arr' File2 File1

对我来说完全失败,除了一般的awk帮助响应外,没有错误消息。

这有可能吗?谢谢。

2 个答案:

答案 0 :(得分:1)

awk 'NR==FNR { arr[NR] = $1; next } {
    for (i = 3; i <= NF; ++i) {
        if ($i == arr[n]) {
            print $2, $i
            n++
            next
        }
    }
    print $2, 0
}' n=1 file2 file1

答案 1 :(得分:1)

另一个awk,将仅打印第一个匹配项

$ awk 'NR==FNR {a[$1]; next} 
               {f2=$2; $1=$2=""; 
                for(k in a) if($0 FS ~ FS k FS) {print f2,k; next}}' file2 file1

15 2
18 5
23 2
25 18

填充FS以消除子字符串匹配。请注意文件的顺序,应首先提供file2。