Shell 使用awk命令递归地比较两个文件

Shell 使用awk命令递归地比较两个文件,shell,awk,Shell,Awk,我想比较两个文件, 1比较每个查询结果。 2仅比较查询输出的第一行 3比较时间第3列,第一个文件时间小于第二个文件时间,然后打印订单号,否则不执行任何操作 文件1: C:\script>call transaction 1OPOP C:\script>Select ID, PO_ID, TIME, DES From Table ID PO_NUM TIME DES -------

我想比较两个文件, 1比较每个查询结果。 2仅比较查询输出的第一行 3比较时间第3列,第一个文件时间小于第二个文件时间,然后打印订单号,否则不执行任何操作

文件1:

C:\script>call transaction 1OPOP

C:\script>Select ID, PO_ID, TIME, DES From Table
ID          PO_NUM          TIME                        DES         
-------     ------------    ---------------             -----
11232323    1OPOP           2012-08-01-23.02.50.040000  SAMPLE  
11232324    1OPOP           2013-09-01-23.02.50.040000  SAMPLE  
11232325    1OPOP           2014-09-01-23.02.50.040000  SAMPLE  
11232326    1OPOP           2015-09-01-23.02.50.040000  SAMPLE
4 record(s) selected.

C:\script>call transaction 1XDXD

C:\script>Select ID, PO_ID, TIME, DES From Table
ID          PO_NUM          TIME                        DES         
-------     ------------    ---------------             -----
11232323    1XDXD           2012-07-01-23.02.50.040000  SAMPLE  
11232324    1XDXD           2013-09-01-23.02.50.040000  SAMPLE  
11232325    1XDXD           2014-08-01-23.02.50.040000  SAMPLE  
3 record(s) selected.

C:\script>call transaction 1IOIO

C:\script>Select ID, PO_ID, TIME, DES From Table
ID          PO_NUM          TIME                        DES         
-------     ------------    ---------------             -----
11232323    1IOIO           2011-06-01-23.02.50.040000  SAMPLE  
11232324    1IOIO           2012-09-01-23.02.50.040000  SAMPLE  
2 record(s) selected.
文件2:

C:\script>call transaction 1OPOP

C:\script>Select ID, PO_ID, TIME, DES From Table
ID          PO_NUM          TIME                    DES         
-------     ------------    ---------------             -----
11232323    1OPOP           2012-09-01-23.02.50.040000  SAMPLE  
11232324    1OPOP           2013-09-01-23.02.50.040000  SAMPLE  
11232325    1OPOP           2014-09-01-23.02.50.040000  SAMPLE  
11232326    1OPOP           2015-09-01-23.02.50.040000  SAMPLE
4 record(s) selected.

C:\script>call transaction 1XDXD

C:\script>Select ID, PO_ID, TIME, DES From Table
ID          PO_NUM          TIME                    DES         
-------     ------------    ---------------             -----
11232323    1XDXD           2012-08-01-23.02.50.040000  SAMPLE  
11232324    1XDXD           2013-09-01-23.02.50.040000  SAMPLE  
11232325    1XDXD           2014-08-01-23.02.50.040000  SAMPLE  
3 record(s) selected.

C:\script>call transaction 1IOIO

C:\script>Select ID, PO_ID, TIME, DES From Table
ID          PO_NUM          TIME                DES         
-------     ------------    ---------------             -----
11232323    1IOIO           2011-05-01-23.02.50.040000  SAMPLE  
11232324    1IOIO           2012-09-01-23.02.50.040000  SAMPLE  
2 record(s) selected.   

您可以尝试以下Perl脚本:

#! /usr/bin/perl

use v5.12;

use File::Slurp qw(read_file);
use Time::Piece;

my $fmt='%Y-%d-%m-%H.%M.%S';
my @files=qw(file1 file2);
my @data;
for my $file (@files) {
    my $str=read_file($file);
    my @a=$str=~/-----\s*\n(.*?)\n\d+ record/sg;
    my $i=0;
    for (@a) {
        my $line=@{[split (/\n/)]}[0];
        my @fld=split(" ",$line);
        my $d=$fld[2];
        my ($date)=$d=~/(.*)\.[^.]*$/;
        $data[$i]={} if ! defined $data[$i];
        $data[$i]->{$file}{time}=Time::Piece->strptime($date, $fmt);
        $data[$i]->{id}=$fld[1];
        $i++;
    }      
}
for my $row (@data) {
    my $t1=$row->{file1}->{time};
    my $t2=$row->{file2}->{time};
    if ($t1>$t2) {
        say $row->{id};
    }
}
awk示例:

awk '/^---/ {b=1;next} b==1{if(NR==FNR) a[$2]=$3; else if(a[$2]<$3) print $2; b=0}' file1 file2
1OPOP
1XDXD

主要区别在于a中的键基于file1中每个查询的第一个结果的ID和PO_NUM。对于第二个文件,将检查结果中的所有条目,以在数组中查找匹配的ID和PO_NUM组合。另外,由于b现在只在第一个文件中起作用,我重新安排了一些条件测试。

你能告诉我们你期望的输入以及到目前为止你做了什么吗?如果你不能减少和简化这一点,那么愿意尝试了解你正在尝试做什么的人数将会非常少,我预计。你能不能只发布两个输入文件,每行有两行,每行有两个字段,代表你的实际问题,这样我们就可以很容易理解,你可以从你得到的答案中推断并应用到你的实际输入中?我指的是输出。但是@EdMorton所说的话在我的脑海中,但我懒得写。从第一个查询中,我们需要从文件中获取值2012-08-01-23.02.50.040000,并与第二个文件中的值进行比较第一个查询2012-09-01-23.02.50.040000。这里file1的值大于file2的值。同样适用于第二次查询。在第三次查询第一个结果窗口中,选择值2011-06-01-23.02.50.040000并与2011-05-01-23.02.50.040000进行比较。这里file1的值小于file2的值,所以我们需要打印po_num 1oio。在上面的例子中,数据是根据月份变化的。时间戳末尾的格式是什么?例如:23.02.50.040000。是小时、分钟、秒还是毫秒?非常感谢您提供这个awk脚本。如我所料,其工作正常。您好n0741337,您能否提供在查询未排序时如何进行比较?如果第二个文件的查询顺序与第一个文件不同,那么是否可以匹配PO_NUM并打印结果?请澄清,您是说Select语句中的响应没有匹配的第一个ID?例如,对于1OPOP,在您的问题中,第二个文件的第一个条目是11232323,但可以改为11232326?或者你是说别的?是的,我是说别的。我有两个问题要问你:1打印$2打印第二个文件的订单号。如何从第一个文件打印订单号。2当订单号不在同一顺序时,用户以错误的顺序执行查询。假设文件1的订单号为1OPOP、1XDXD、1OIO文件2的订单号为1OPOP、1OIO、1XD。在第二个文件中,第二个和第三个事务以及查询和输出交换了其位置。所以在这种情况下,程序必须运行整个文件来搜索匹配的PO_NUM。我知道这很难做到。但现在请回答第一个问题。2美元是一个匹配点,它是否从文件2打印并不重要,因为文件1中的1OPOP必须与文件2中的1OPOP匹配。它必须匹配,否则将不打印任何内容。我展示的第二个awk已经允许第二个文件中的事务发生故障。但是,我怀疑您希望在输出1OPOP、1XDXD中保留文件1中事务的顺序,而第二个awk不会这样做。让我知道。谢谢你提供这个脚本。工作正常。
awk 'NR==FNR {if($0 ~ /^---/) {b=1} else if(b==1) {a[$1$2]=$3; b=0} next} $1$2 in a {if(a[$1$2]<$3) print $2}' file1 file2