想象一下我有file1:
2 luke
3 matthew
4 mark
7 john
我有
1 chicken
2 beef
5 lamb
6 fish
我想要以下内容:
1 [tab]chicken
2 luke[tab]beef
3 matthew[tab]
4 mark[tab]
5 lamb[tab]
6 fish[tab]
7 [tab]john
喜欢"加入"但我也想要其他专栏。我知道我可以使用3" comm" s并使用sort来调整它但是有一个命令可以做到吗?
答案 0 :(得分:3)
您只需要使用join
的几个选项:
join -a1 -a2 -o 0,1.2,2.2 -e $'\t' tmp1.txt tmp2.txt
-a1
和-a2
告诉join
输出文件1和文件2中无法配对的行(因此包含两个文件中的所有行)。 -o
在输出中指定三列:连接字段(0),第一个文件中的第二列和第二个文件中的第二列。 -e
指定用于填充空字段的字符串(未找到字段)。 $'\t'
是bash
扩展名;传递制表符的更兼容方式是-e $(printf '\t')
。
答案 1 :(得分:1)
您也可以使用AWK:
awk 'FNR==NR{a[$1]=$2; i++; next}{ b[$1]=$2; i++} END { OFS="\t"; for (n=1;n<i;++n) print n, a[n], b[n] }' file1 file2
这会经过file1
(第一个{block}
)和file2
(第二个{block}
,构建由第一列中的数字索引的数组。然后在最后打印输出每个数组中的所有值。
答案 2 :(得分:0)
这会使用制表符填充空字段,但字段仍以空格分隔。
join -a1 -a2 -o 0,1.2,2.2 -e $'\t' file1 file2
1 chicken
2 luke beef
3 matthew
4 mark
5 lamb
6 fish
7 john
要查看空白字符,请将输出通过管道传输到| od -c
要准确获得所需的输出,请使用awk:
awk '
{
ids[$1]
if (NR==FNR)
f1[$1]=$2
else
f2[$1]=$2
}
END {
n = asorti(ids, sorted_ids)
for (i=1; i<=n; i++)
printf "%d %s\t%s\n", sorted_ids[i], f1[sorted_ids[i]], f2[sorted_ids[i]]
}
' file1 file2
1 chicken
2 luke beef
3 matthew
4 mark
5 lamb
6 fish
7 john
答案 3 :(得分:0)
这个awk应该可以工作:
awk 'FNR==NR{a[$1]=$2;next} $1 in a{print $1, $2, a[$1];delete a[$1];next} {print $1, $2, ""}
END {for (i in a) print i, a[i]}' OFS='\t' f2 f1|sort -nk1
1 chicken
2 luke beef
3 matthew
4 mark
5 lamb
6 fish
7 john
答案 4 :(得分:0)
以下是awk
的另一种方式。只需将[tab]
替换为\t
即可。
awk '
NR==FNR { a[$1] = $2 "[tab]"; next }
($1 in a) { a[$1] = a[$1] $2; next }
{ a[$1] = "[tab]" $2 }
END {
n = asorti(a, s);
for (x = 1; x <= n; x++)
print s[x], a[s[x]]}
' file1 file2
1 [tab]chicken
2 luke[tab]beef
3 matthew[tab]
4 mark[tab]
5 [tab]lamb
6 [tab]fish
7 john[tab]