linux - 比较两个 csv 文件的第 1 列并找到与 >= && < 最接近的匹配项,然后打印对

标签 linux

这里有一些例子(大文件的片段)。第一个文件示例的文件 1 大于文件 2,并且一些时间戳匹配,而一些则不匹配。所需的输出将带有标题,但如果太难,我可以稍后将它们放入。第二个文件示例的 file1 小于 file2,因此我需要附加一个与 file2 行最匹配的 file1 行(使用 >= 和 < 逻辑)。正如您所看到的,以秒为单位的时间因文件和示例而异,因此有些会完全匹配,而有些则接近。

我可以很容易地找到所有精确的时间匹配,但不是 > 和 < 比较。

这种代码可以工作,但会遗漏许多开头的行。我是
尝试重新排列此代码以提供以下“所需”输出,但没有
成功。

awk -F, '
BEGIN           {CNT+=2
            }
NR == FNR       {a[NR] = $0
             b[NR] = $1
             next
            }
$1 >= b[CNT]    {CNT++
            }
$1 <  b[CNT]    {print a[CNT-1]
             print $0, RS
            }
' file1 file2

文件 1:

TIMEFORMATTED,G_TP01_OPER_ID,G_TP01_OPER_ID(RAW),G_TP02_PROC_NO,G_TP02_PROC_NO(R    
2016/05/25 16:25:19,0,0,0,NO_DEF,-2147483647
2016/05/25 16:25:20,0,0,0,NO_DEF,-2147483648
2016/05/25 16:25:21,0,0,0,NO_DEF,-2147483649
2016/05/25 16:25:22,0,0,0,NO_DEF,-2147483650
2016/05/25 16:25:23,0,0,0,NO_DEF,-2147483651
2016/05/25 16:25:24,0,0,0,NO_DEF,-2147483652
2016/05/25 16:25:25,0,0,0,NO_DEF,-2147483653
2016/05/25 16:25:26,0,0,0,NO_DEF,-2147483654
2016/05/25 16:25:27,0,0,0,NO_DEF,-2147483655

文件 2:

TIMEFORMATTED,HDR_SYNC,HDR_SEC,HDR_MSEC,G_CCSDS_VERSION,G_CCSDS_VERSION(RAW)
2016/05/25 16:25:22,464374526,1464193527,206,0,0
2016/05/25 16:25:26,464374526,1464193532,206,0,0
2016/05/25 16:25:31,464374526,1464193537,207,0,0

期望的输出:

TIMEFORMATTED,G_TP01_OPER_ID,G_TP01_OPER_ID(RAW),G_TP02_PROC_NO,G_TP02_PROC
2016/05/25 16:25:22,0,0,0,NO_DEF,-2147483650
TIMEFORMATTED,HDR_SYNC,HDR_SEC,HDR_MSEC,G_CCSDS_VERSION,G_CCSDS_VERSION(RAw
2016/05/25 16:25:22,464374526,1464193527,206,0,0          
TIMEFORMATTED,G_TP01_OPER_ID,G_TP01_OPER_ID(RAW),G_TP02_PROC_NO,G_TP02_PROC
2016/05/25 16:25:26,0,0,0,NO_DEF,-2147483654
TIMEFORMATTED,HDR_SYNC,HDR_SEC,HDR_MSEC,G_CCSDS_VERSION,G_CCSDS_VERSION(RAw
2016/05/25 16:25:26,464374526,1464193532,206,0,0    
TIMEFORMATTED,G_TP01_OPER_ID,G_TP01_OPER_ID(RAW),G_TP02_PROC_NO,G_TP02_PROC
2016/05/25 16:25:27,0,0,0,NO_DEF,-   2147483655
TIMEFORMATTED,HDR_SYNC,HDR_SEC,HDR_MSEC,G_CCSDS_VERSION,G_CCSDS_VERSION(RAW
2016/05/25 16:25:31,464374526,1464193537,207,0,0

第二个例子:

文件 1:

TIMEFORMATTED,G_TP01_OPER_ID,G_TP01_OPER_ID(RAW),G_TP02_PROC_NO,G_TP02_PROC_NO(R
2014/04/07 16:00:30,0,0,0,NO_DEF,-2147483647
2014/04/07 16:00:35,0,0,0,NO_DEF,-2147483648
2014/04/07 16:00:40,0,0,0,NO_DEF,-2147483649
2014/04/07 16:00:45,0,0,0,NO_DEF,-2147483650
2014/04/07 16:00:50,0,0,0,NO_DEF,-2147483651
2014/04/07 16:00:55,0,0,0,NO_DEF,-2147483652
2014/04/07 16:00:60,0,0,0,NO_DEF,-2147483653

文件 2:

TIMEFORMATTED,CCSDS_VERSION,CCSDS_VERSION(RAW),CCSDS_TYPE,CCSDS_TYPE(RAW),CCSDS_2HDR_FLAG,CCSDS_2HDR_FLAG(RAW),ID
2014/04/07 16:00:43,0,0,0,0,1,1,544
2014/04/07 16:00:45,0,0,0,0,1,3,544
2014/04/07 16:00:47,0,0,0,0,1,1,544
2014/04/07 16:00:49,0,0,0,0,4,1,544
2014/04/07 16:00:51,0,0,0,0,1,1,544
2014/04/07 16:00:53,0,0,0,0,1,7,544
2014/04/07 16:00:55,0,0,0,0,8,1,544
2014/04/07 16:00:57,0,0,0,0,1,2,544
2014/04/07 16:00:59,0,0,0,0,3,1,544
2014/04/07 16:00:61,0,0,0,0,1,1,544
2014/04/07 16:00:63,0,0,0,0,1,9,544
2014/04/07 16:00:65,0,0,0,0,4,1,544
2014/04/07 16:00:67,0,0,0,0,1,1,544

输出:我更喜欢像第一个输出示例那样附加标题,但是
如果它更容易,我会接受它。

2014/04/07 16:00:40,0,0,0,NO_DEF,-2147483649
2014/04/07 16:00:43,0,0,0,0,1,1,544
2014/04/07 16:00:45,0,0,0,NO_DEF,-2147483650
2014/04/07 16:00:45,0,0,0,0,1,3,544
2014/04/07 16:00:45,0,0,0,NO_DEF,-2147483650
2014/04/07 16:00:47,0,0,0,0,1,1,544
2014/04/07 16:00:45,0,0,0,NO_DEF,-2147483650
2014/04/07 16:00:49,0,0,0,0,4,1,544
2014/04/07 16:00:50,0,0,0,NO_DEF,-2147483651
2014/04/07 16:00:51,0,0,0,0,1,1,544
2014/04/07 16:00:50,0,0,0,NO_DEF,-2147483651
2014/04/07 16:00:53,0,0,0,0,1,7,544
2014/04/07 16:00:55,0,0,0,NO_DEF,-2147483652
2014/04/07 16:00:55,0,0,0,0,8,1,544
2014/04/07 16:00:55,0,0,0,NO_DEF,-2147483652
2014/04/07 16:00:57,0,0,0,0,1,2,544
2014/04/07 16:00:55,0,0,0,NO_DEF,-2147483652
2014/04/07 16:00:59,0,0,0,0,3,1,544
2014/04/07 16:00:60,0,0,0,NO_DEF,-2147483653
2014/04/07 16:00:61,0,0,0,0,1,1,544

最佳答案

好的,就到这里。我在文件 1 前添加了一个 1,,在文件 2 前添加了一个 2,,这样我就可以再次将它们分开。这是脚本的前两行。

然后在第 3 行的时间戳(现在是字段 2)上将两个文件合并在一起。假设文件已经排序,合并操作非常有效。我还在第一个字段上排序(次要),因为如果文件戳相同,我们希望来自 file1 的行排在 file2 之前。

perl 脚本可以:

  1. 删除第一个字段(将其保存到 $1)
  2. 如果 $1 == "1",保存 file1 的最新行,但不打印它。
  3. 当它看到类型“2”时,它会打印最近的类型“1”行 ($last) 和类型“2”行。

a.sh 脚本:

pa-dev00$ cat a.sh
perl -pe 's/^/1,/' file1 > file1a
perl -pe 's/^/2,/' file2 > file2a
sort -m -t, -k2,2 -k1,1 file1a file2a | perl -ne 's/^(.),//; if ($1 == "1") {$last=$_; } else { print $last; print $_; }'

这是输出

pa-dev00$ ./a.sh
2014/04/07 16:00:40,0,0,0,NO_DEF,-2147483649
2014/04/07 16:00:43,0,0,0,0,1,1,544
2014/04/07 16:00:45,0,0,0,NO_DEF,-2147483650
2014/04/07 16:00:45,0,0,0,0,1,3,544
2014/04/07 16:00:45,0,0,0,NO_DEF,-2147483650
2014/04/07 16:00:47,0,0,0,0,1,1,544
2014/04/07 16:00:45,0,0,0,NO_DEF,-2147483650
2014/04/07 16:00:49,0,0,0,0,4,1,544
2014/04/07 16:00:50,0,0,0,NO_DEF,-2147483651
2014/04/07 16:00:51,0,0,0,0,1,1,544
2014/04/07 16:00:50,0,0,0,NO_DEF,-2147483651
2014/04/07 16:00:53,0,0,0,0,1,7,544
2014/04/07 16:00:55,0,0,0,NO_DEF,-2147483652
2014/04/07 16:00:55,0,0,0,0,8,1,544
2014/04/07 16:00:55,0,0,0,NO_DEF,-2147483652
2014/04/07 16:00:57,0,0,0,0,1,2,544
2014/04/07 16:00:55,0,0,0,NO_DEF,-2147483652
2014/04/07 16:00:59,0,0,0,0,3,1,544
2014/04/07 16:00:60,0,0,0,NO_DEF,-2147483653
2014/04/07 16:00:61,0,0,0,0,1,1,544
2014/04/07 16:00:60,0,0,0,NO_DEF,-2147483653
2014/04/07 16:00:63,0,0,0,0,1,9,544
2014/04/07 16:00:60,0,0,0,NO_DEF,-2147483653
2014/04/07 16:00:65,0,0,0,0,4,1,544
2014/04/07 16:00:60,0,0,0,NO_DEF,-2147483653
2014/04/07 16:00:67,0,0,0,0,1,1,544

这应该非常有效。每一步都应该是线性的,因此它只会随着文件的大小而缩放。

关于linux - 比较两个 csv 文件的第 1 列并找到与 >= && < 最接近的匹配项,然后打印对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38600061/

相关文章:

linux - 如何使用shell脚本root登录远程机器

python - 在 Linux 上运行 Tensorflow 代码时出错

linux - 在 Postfix 中配置备份邮件中继

django - 在后台启动 ./manage.py runworker

c++ - 为什么 fstream 不能在 Linux 中写入文件?

能够模拟非虚拟方法和 C 函数的 C++ 模拟框架

从 Go 调用 setns 为 mnt 命名空间返回 EINVAL

linux - 如何在 Linux 上构建 BlackBerry 应用程序?

linux - "failed to execute command: permission denied"Ubuntu 18.04.3 LTS

c++ - QWidget 外部 GUI 线程上的绘画问题