我有两个文件。我想在file2的基础上打印file1的数据。
File1中:
a 1
b 2
c 3
d 4
e 1
f 5
g 1
文件2:
1 100
2 200
3 400
4 600
5 700
使用以下命令:
awk 'NR==FNR{a[$2]=$1;next}$1 in a{print a[$1] " " $2}' file1 file2
我得到了以下输出:
g 100
b 200
c 400
d 600
f 700
但我不希望在数组中覆盖重复值。 期望的输出:
a 100
e 100
g 100
b 200
c 400
d 600
f 700
是否可以在awk脚本中将重复键存储在数组中,如C ++中的multimap。或者还有另一种方法吗?请帮帮我。
答案 0 :(得分:4)
如果(且仅当)第二个文件的第一个字段(单个数字的数字)是唯一的,您可以转动逻辑并使用该字段作为数组的键:
$ awk 'FNR==NR { a[$1] = $2; next } $2 in a {print $1, a[$2]} ' file2 file1
a 100
b 200
c 400
d 600
e 100
f 700
g 100
现在输出顺序是file1的顺序,所以不是你想要的,但到sort -nk2
的管道将解决这个问题。
如果第一个文件有第二个字段不在第二个文件中的行(例如h 9
),那么该怎么做的边界情况。 $2 in a
条件将完全跳过这些条件。如果没有这些条件,它们将被打印,并带有一个空的第二个字段(输出中只有h[space]
)。
答案 1 :(得分:3)
使用GNU awk实现真正的多维数组:
$ awk 'NR==FNR{a[$2][$1]=$1;next} $1 in a{for (i in a[$1]) print a[$1][i], $2}' file1 file2
a 100
e 100
g 100
b 200
c 400
d 600
f 700
其他问题:
$ awk 'NR==FNR{a[$2]=a[$2] FS $1;next} $1 in a{split(a[$1],b); for (i in b) print b[i], $2}' file1 file2
a 100
e 100
g 100
b 200
c 400
d 600
f 700
由于in
运算符,每个键的输出顺序将是随机的,如果问题让我们知道您需要什么顺序。
答案 2 :(得分:2)
您可以使用join
命令
在join
命令之前,您必须使用sort
命令对文件进行排序。
$ sort -k 2 file1 > file1_sort
$ sort -k 1 file2 > file2_sort
$ join -1 2 -2 1 file1_sort file2_sort -o 1.1,2.2 > new_file
$ rm file1_sort
$ rm file2_sort
$ cat new_file
a 100
e 100
g 100
b 200
c 400
d 600
f 700
$ join -1 2 -2 1 <(sort -k2 file1) <(sort file2) -o 1.1,2.2
a 100
e 100
g 100
b 200
c 400
d 600
f 700
答案 3 :(得分:1)
在第一个回复后回复标题而不是OP本身,第二个版本为OP(原始回复完全修改)
awk 'FNR==NR{R[$1]=$2;next}{$2=R[$2]}7' File2 File1