我有两个文本文件
档案1
number,name,account id,vv,sfee,dac acc,TDID
7000,john,2,0,0,1,6
7001,elen,2,0,0,1,7
7002,sami,2,0,0,1,6
7003,mike,1,0,0,2,1
8001,nike,1,2,4,1,8
8002,paul,2,0,0,2,7
文件2
number,account id,dac acc,TDID
7000,2,1,6
7001,2,1,7
7002,2,1,6
7003,1,2,1
我想比较这两个文本文件。如果文件2的四列在文件1中,则相等意味着我想要像这样输出
7000,john,2,0,0,1,6
7001,elen,2,0,0,1,7
7002,sami,2,0,0,1,6
7003,mike,1,0,0,2,1
nawk -F"," 'NR==FNR {a[$1];next} ($1 in a)' file2.txt file1.txt
..这适用于比较两个文件中的两个单列。我想比较多列。有谁有建议?
编辑:来自OP的评论:
nawk -F"," 'NR==FNR {a[$1];next} ($1 in a)' file2.txt file1.txt
..这适用于比较两个文件中的两个单列。我想比较多列。你有什么建议吗?
答案 0 :(得分:3)
此awk单行程序适用于 未排序 文件的多列:
awk -F, 'NR==FNR{a[$1,$2,$3,$4]++;next} (a[$1,$3,$6,$7])' file1.txt file2.txt
为了使其正常工作,用于输入的第一个文件(在我的示例中为file1.txt)必须是仅包含4个字段的文件:
7000,2,1,6
7001,2,1,7
7002,2,1,6
7003,1,2,1
7000,john,2,0,0,1,6
7000,john,2,0,0,1,7
7000,john,2,0,0,1,8
7000,john,2,0,0,1,9
7001,elen,2,0,0,1,7
7002,sami,2,0,0,1,6
7003,mike,1,0,0,2,1
7003,mike,1,0,0,2,2
7003,mike,1,0,0,2,3
7003,mike,1,0,0,2,4
8001,nike,1,2,4,1,8
8002,paul,2,0,0,2,7
$ awk -F, 'NR==FNR{a[$1,$2,$3,$4]++;next} (a[$1,$3,$6,$7])' file1.txt file2.txt
7000,john,2,0,0,1,6
7001,elen,2,0,0,1,7
7002,sami,2,0,0,1,6
7003,mike,1,0,0,2,1
或者,您也可以使用以下语法,该语法与您问题中的语法更接近,但不太可读恕我直言
awk -F, 'NR==FNR{a[$1,$2,$3,$4];next} ($1SUBSEP$3SUBSEP$6SUBSEP$7 in a)' file1.txt file2.txt
答案 1 :(得分:1)
TxtSushi看起来像你想要的。它允许使用SQL处理CSV文件。
答案 2 :(得分:1)
这不是一个优雅的单行,但你可以用perl来做。
#!/usr/bin/perl
open A, $ARGV[0];
while(split/,/,<A>) {
$k{$_[0]} = [@_];
}
close A;
open B, $ARGV[1];
while(split/,/,<B>) {
print join(',',@{$k{$_[0]}}) if
defined($k{$_[0]}) &&
$k{$_[0]}->[2] == $_[1] &&
$k{$_[0]}->[5] == $_[2] &&
$k{$_[0]}->[6] == $_[3];
}
close B;
答案 3 :(得分:0)
快速回答:使用cut
拆分您需要的字段,并diff
来比较结果。
答案 4 :(得分:0)
这既不高效又不漂亮,但它会完成工作。它不是最有效的实现,因为它多次解析file1,但它不会将整个文件读入RAM,因此与简单的脚本方法相比具有一些优势。
sed -n '2,$p' file1 | awk -F, '{print $1 "," $3 "," $6 "," $7 " " $0 }' | \
sort | join file2 - |awk '{print $2}'
这可以如下工作
sed -n '2,$p' file1
将file1发送到没有标题行的STDOUT 为了使其正常工作,您必须确保在运行命令之前对file2进行排序。
针对您的示例数据运行此操作会产生以下结果
7000,john,2,0,0,1,6 7001,elen,2,0,0,1,7 7002,sami,2,0,0,1,6 7003,mike,1,0,0,2,1
修改强>
我从您的评论中注意到您收到了排序错误。如果在运行管道命令之前对file2进行排序时发生此错误,那么您可以拆分文件,对每个部分进行排序,然后再将它们重新组合在一起。
像这样的东西会为你做那件事
mv file2 file2.orig
for i in 0 1 2 3 4 5 6 7 8 9
do
grep "^${i}" file2.orig |sort > file2.$i
done
cat file2.[0-9] >file2
rm file2.[0-9] file2.orig
如果您的文件未在所有前导数字范围内均匀分布,则可能需要修改传递给的变量。
答案 5 :(得分:0)
测试不是很好,但这可能会有效:
join -t, file1 file2 | awk -F, 'BEGIN{OFS=","} {if ($3==$8 && $6==$9 && $7==$10) print $1,$2,$3,$4,$6,$7}'
(当然,这假定输入文件已排序)。
答案 6 :(得分:0)
统计包R可以轻松处理多个csv表。 请参阅An Intro. to R或R for Beginners。