将行中的每个字段与另一个文件中的列交叉引用

将行中的每个字段与另一个文件中的列交叉引用

我没有使用 awk、sed、grep 等的经验。试图表达我的问题使它看起来比应有的更令人困惑,所以我将从一个我想要实现的目标的例子开始。

input1

A B C D  
A B C  
A B C D E F  

input2

v A  
c B  
c C  
c D  
v E  

output

A B C D  
v c c c  
A B C  
v c c  
A B C D E F  
v c c c v Ø

所以基本上我有2个输入文件。

input1每行都有不同数量的字段。
input2每行都有 2 个字段。

我需要output其中的每一行的位置,input1将首先打印整行及其所有字段,然后对于 的下一行,它将从的第二个字段中output查找该行的每个字段的内容。然后打印该行的第一个字段,如果在 中找不到该内容,则打印。重复此操作,直到最后一个字段,将结果打印在一行中。然后对 中的每一行执行相同的操作。input1input2input2Øinput2input1

由于我将执行类似的稍微不同的任务,因此非常感谢对命令的每个部分的作用的简要解释。提前致谢。

答案1

$ awk 'FNR == NR {   a[$2] = $1; next }
                 {   print
                     line = (a[$1] ? a[$1] : "Ø")
                     for (i = 2; i <= NF; ++i) {
                        line = line OFS (a[$i] ? a[$i] : "Ø")
                     }
                     printf("%s\n", line)
                 }' input2 input1
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø

也就是说,如果我们从第一个文件 ( input2) 中读取,请使用每个字符应替换为的符号填充查找表。

读取第二个文件 ( input1) 时,输出输入行,然后循环遍历字段并使用查找表中的正确符号构造一个字符串。如果查找表中缺少符号,请插入Ø

然后输出带有终止换行符的组装字符串。


您也可以将其转换为适当的脚本:

#!/usr/bin/awk -f

FNR == NR {   a[$2] = $1; next }
          {   print
              line = (a[$1] ? a[$1] : "Ø")
              for (i = 2; i <= NF; ++i) {
                  line = line OFS (a[$i] ? a[$i] : "Ø")
               }
                     printf("%s\n", line)
          }

然后使其可执行(chmod +x script)并像这样运行它:

$ ./script input2 input1
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø

答案2

这似乎有效:

awk 'NR==FNR { code[$2]=$1 } NR!=FNR {print; for( i=0; i<=NF; i++) { printf( "%s ", code[$i] ) }; printf "\n" }' input2 input1

NR==FNR块仅在指定的第一个文件上运行(其中处理的总记录数等于迄今为止的总数),并填充用于稍后输出的数组。

NR!=FNR块仅在后续文件上运行,首先输出给定的输入行,然后逐步执行它并使用每个值作为数组查找的下标来确定是否输出vc

在这个迭代系列之后,输出换行符。

相关内容