我有两个文件。第一个文件有 11 列,例如:
1 2 3 4 5 6 7 8 9 10 11
第二个有 10 列,可能如下所示:
11 22 33 44 55 66 77 88 99 100
我想做的是查看 file1,如果第 7 列是某个值,例如介于 14 和 15 之间,则将 file1 的第 9 列替换为 file2 中第 9 列的值。因此,在上面的示例中,file1 将被重写为:
1 2 3 4 5 6 7 8 99 10 11
检查列是否在某个值之间很简单:
awk '$7 < 15 && $7 >= 14
但是,我在用 file2 中的值替换 file1 的第 9 列时遇到问题。 file1 不一定只是一行。它可以有任意数量的行,并且在值介于 14 和 15 之间的每个实例中,都需要替换第 9 列。如果该值小于 14 或大于 15,则列应保持原样。我不认为这应该很困难,但我没有任何运气。我们将不胜感激,并提前致谢!
答案1
要使用第 9 个字段的值,仅使用第 1 行file2
awk 'NR==1{a=$9}FNR==NR{next}14<=$7&&$7<15{$9=a}1' file2 file1
答案2
对两个单独的文件进行逐行处理,awk
其中两个文件具有相同的行数,并且您只关心另一个文件中的相应行,也就是说,您想查看 file1 的第 1 行和 file2 的第 1 行,然后查看每个文件的第 2 行,依此类推......
你最好使用paste file1 file2 | awk '{...}'
当 file1 的每一行具有相同数量的字段并且 file2 的每一行具有相同数量的字段时尤其如此(但它们不必具有彼此相同的字段数量。)
如果它们具有可变数量的字段,因此您需要确定哪些字段来自 file1 以及哪些字段来自 file2,则可以为paste
您知道不会出现在这两个文件中的命令指定分隔符,然后将每一行分割为awk
基于在该分隔符上。例如:
paste -d: file1 file2 | awk -F: '{NF1=split($1,file1," "); NF2=split($2,file2," "); if (file1[7] <= 15 && file1[7] >= 14) { file1[9] = file2[9] }; for (i=1; i<=NF1; i++) {printf file1[i] " "}; printf "\n";}'
这满足了您的要求,但它的作用还不止于此;它设置您的awk
变量,以便您同时拥有来自 和 的行file1
,file2
以及NF1
每个NF2
文件中找到的字段数。
如果我有时间学习getline
中的函数awk
,我将用“如何使用 getline() 来做到这一点”来更新这个答案。 :)