Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何比较unix中具有多个字段的两个文本文件_Linux_Perl_Unix_Awk - Fatal编程技术网

Linux 如何比较unix中具有多个字段的两个文本文件

Linux 如何比较unix中具有多个字段的两个文本文件,linux,perl,unix,awk,Linux,Perl,Unix,Awk,我有两个文本文件 文件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 7

我有两个文本文件

  • 文件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}($a中的1)'file2.txt file1.txt
。。这适用于比较两个文件中的两个单列。我想比较多列。有人有什么建议吗


编辑:根据OP的评论:

nawk -F"," 'NR==FNR {a[$1];next} ($1 in a)' file2.txt file1.txt

。。这适用于比较两个文件中的两个单列。我想比较多列。你有什么建议吗?

快速回答:使用
cut
分割出你需要的字段,然后使用
diff
比较结果。

快速回答:使用
cut
分割出你需要的字段,然后使用
diff
比较结果。

看起来像你想要的。它允许使用SQL处理CSV文件。

看起来像您想要的。它允许使用SQL处理CSV文件。

这不是一个优雅的单行程序,但您可以使用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;
#/usr/bin/perl
打开一个$ARGV[0];
while(split/,/,){
$k{$\[0]}=[@\];
}
关闭A;
未结B$ARGV[1];
while(split/,/,){
打印联接(“,”,@{$k{$\[0]})如果
已定义($k{$\[0]})&&
$k{$\[0]}->[2]==$\[1]&&
$k{$\[0]}->[5]==$\[2]&&
$k{$\[0]}->[6]==$\[3];
}
关闭B;

这不是一个优雅的单行程序,但您可以使用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;
#/usr/bin/perl
打开一个$ARGV[0];
while(split/,/,){
$k{$\[0]}=[@\];
}
关闭A;
未结B$ARGV[1];
while(split/,/,){
打印联接(“,”,@{$k{$\[0]})如果
已定义($k{$\[0]})&&
$k{$\[0]}->[2]==$\[1]&&
$k{$\[0]}->[5]==$\[2]&&
$k{$\[0]}->[6]==$\[3];
}
关闭B;

这既不高效也不美观,但它可以完成工作。它不是最有效的实现,因为它多次解析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,但不带头行
  • 第一个awk命令以与file2相同的格式打印file1中的4个“键字段”,后跟一个空格,后跟file1的内容
  • sort命令确保file1与file2的顺序相同
  • join命令连接file2和STDOUT,仅写入file2中具有匹配记录的记录
  • 最后一个awk命令只打印file1的原始部分
  • 为了使其工作,您必须确保在运行命令之前对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
    如果您的文件没有均匀地分布在整个前导数字范围内,您可能需要修改传递给的变量。

    这既不高效也不美观,但它将完成工作。它不是最有效的实现,因为它多次解析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,但不带头行
  • 第一个awk命令以与file2相同的格式打印file1中的4个“键字段”,后跟一个空格,后跟file1的内容
  • sort命令确保file1与file2的顺序相同
  • join命令连接file2和STDOUT,仅写入file2中具有匹配记录的记录
  • 最后一个awk命令只打印file1的原始部分
  • 为了使其工作,您必须确保在运行命令之前对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
    如果文件在整个前导数字范围内分布不均匀,则可能需要修改传递给的变量。

    测试得不太好,但这可能有效:

    join -t, file1 file2 | awk -F, 'BEGIN{OFS=","} {if ($3==$8 && $6==$9 && $7==$10) print $1,$2,$3,$4,$6,$7}'
    

    (当然,这是假设输入文件已排序)。

    没有经过很好的测试,但这可能会起作用:

    join -t, file1 file2 | awk -F, 'BEGIN{OFS=","} {if ($3==$8 && $6==$9 && $7==$10) print $1,$2,$3,$4,$6,$7}'
    

    (当然,这假设输入文件已排序)。

    此awk单行程序适用于未排序的文件上的多列:

    awk-F,'NR==FNR{a[$1,$2,$3,$4]++;next}(a[$1,$3,$6,$7])file1.txt file2.txt

    为了使其工作,第一个用于输入的文件(在我的示例中为file1.txt)必须是只有4个字段的文件,如下所示:

    file1.txt file2.txt 输出 或者,您也可以使用以下语法,该语法与您的问题中的语法更接近,但不太可读

    awk -F, 'NR==FNR{a[$1,$2,$3,$4];next} ($1SUBSEP$3SUBSEP$6SUBSEP$7 in a)' file1.txt file2.txt
    

    此awk one liner适用于未排序的文件上的多列:

    awk-F,'NR==FNR{a[$1,$2,$3,$4]++;next}(a[$1,$3,$6,$7])file1.txt file2.txt

    为了使其工作,第一个用于输入的文件(在我的示例中为file1.txt)必须是只有4个字段的文件,如下所示:

    file1.txt file2.txt 输出 或者,您也可以使用以下语法,该语法与您的问题中的语法更接近,但不太可读

    awk -F, 'NR==FNR{a[$1,$2,$3,$4];next} ($1SUBSEP$3SUBSEP$6SUBSEP$7 in a)' file1.txt file2.txt
    
    统计软件包可以非常轻松地处理多个csv表。 请参阅或。

    统计软件包可以非常轻松地处理多个csv表。
    请参阅或。

    谢谢您的评论。但这不是我想要的。。。我知道如何在两个单列之间比较两个文本文件。但是我想比较多列..没有什么能阻止您使用
    cut
    提取多列进行比较。还是我遗漏了什么?nawk-F“,”NR==FNR{a[$1];next}($a中的1)’file2.txt file1.txt。。这适用于比较两个文件中的两个单列。我想比较多列。你有什么建议吗?重读了你的问题,我的朋友