![根据前两个或三个字段的匹配连接两行详细信息](https://linux22.com/image/953892/%E6%A0%B9%E6%8D%AE%E5%89%8D%E4%B8%A4%E4%B8%AA%E6%88%96%E4%B8%89%E4%B8%AA%E5%AD%97%E6%AE%B5%E7%9A%84%E5%8C%B9%E9%85%8D%E8%BF%9E%E6%8E%A5%E4%B8%A4%E8%A1%8C%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AF.png)
我正在寻求帮助从单个 csv 文件中提取/合并数据。
该文件包含几个月内船舶的到达和离开时间。到达和离开的详细信息位于不同的行上(回车符),字段之间用逗号分隔。有些字段是重复的。
我想将两行合并为一行,只保留唯一字段,并将结果输出到文件中。一艘船可以多次停靠港口,即不同的日期,所以我认为搜索可能会使用前两个或三个字段(日期、船只和 IMO 编号)来查找相应的行?
以下是一小部分数据样本。
Date,Vessel,IMO_No,Agent1,Move,Berth,Time,FromPort,ToPort,Trade
6 Nov 23,Royal Princess,9584712,MCKAY,Arrival,Beach Street,12:15,Fiordland,Lyttelton,CRUISE
6 Nov 23,Royal Princess,9584712,MCKAY,Departure,Beach Street,21:00,Fiordland,Lyttelton,CRUISE
19 Nov 23,Grand Princess,9104005,MCKAY,Arrival,Beach Street,07:00,Fiordland,Lyttelton,CRUISE
19 Nov 23,Noordam,9230115,MCKAY,Arrival,C/T,08:00,Fiordland,Timaru,CRUISE
19 Nov 23,Grand Princess,9104005,MCKAY,Departure,Beach Street,18:00,Fiordland,Lyttelton,CRUISE
19 Nov 23,Noordam,9230115,MCKAY,Departure,C/T,18:00,Fiordland,Timaru,CRUISE
理想的输出文件
6 Nov 23,Royal Princess,9584712,MCKAY,Arrival,Beach Street,12:15,Departure,21:00,Fiordland,Lyttelton,CRUISE
19 Nov 23,Grand Princess,9104005,MCKAY,Arrival,Beach Street,07:00,Departure,18:00,Fiordland,Lyttelton,CRUISE
19 Nov 23,Noordam,9230115,MCKAY,Arrival,C/T,08:00,Departure,18:00,Fiordland,Timaru,CRUISE
注意:我假设解决方案可以重新排序或删除字段。
我在网上搜索了各种提示和技巧。建议包括 AWK、SED 和 GREP,但我已经很久没用过这些命令了,而且我只完成了部分目标(到目前为止已经 4 个小时了)。我希望更擅长编程/脚本的人会发现这很简单。
提前致谢。
答案1
我会考虑采用数据库方法来实现这样的功能。例如,使用csvsql
基于 Python 的工具csvkit
(可从 Ubuntu存储库获取软件包universe
):
csvsql --no-inference --query '
SELECT a.Date,a.Vessel,a.IMO_No,a.Agent1,a.Move,a.Berth,a.Time,d.Move,d.Time,a.FromPort,d.ToPort,a.Trade
FROM
(SELECT * FROM file WHERE Move = "Arrival") a INNER JOIN (SELECT * FROM file WHERE Move = "Departure") d
ON
a.Vessel = d.Vessel AND a.IMO_No = d.IMO_No
' file.csv
Date,Vessel,IMO_No,Agent1,Move,Berth,Time,Move,Time,FromPort,ToPort,Trade
6 Nov 23,Royal Princess,9584712,MCKAY,Arrival,Beach Street,12:15,Departure,21:00,Fiordland,Lyttelton,CRUISE
19 Nov 23,Grand Princess,9104005,MCKAY,Arrival,Beach Street,07:00,Departure,18:00,Fiordland,Lyttelton,CRUISE
19 Nov 23,Noordam,9230115,MCKAY,Arrival,C/T,08:00,Departure,18:00,Fiordland,Timaru,CRUISE
请注意,我省略了约束,a.Date = d.Date
因为船只可能会在稍后的日期出发 - 如果这是真的,您可能希望将其添加d.Date
到所选的输出字段。