我没有使用 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
查找该行的每个字段的内容。然后打印该行的第一个字段,如果在 中找不到该内容,则打印。重复此操作,直到最后一个字段,将结果打印在一行中。然后对 中的每一行执行相同的操作。input1
input2
input2
Ø
input2
input1
由于我将执行类似的稍微不同的任务,因此非常感谢对命令的每个部分的作用的简要解释。提前致谢。
答案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
块仅在后续文件上运行,首先输出给定的输入行,然后逐步执行它并使用每个值作为数组查找的下标来确定是否输出v
或c
。
在这个迭代系列之后,输出换行符。