根据前两个或三个字段的匹配连接两行详细信息

根据前两个或三个字段的匹配连接两行详细信息

我正在寻求帮助从单个 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到所选的输出字段。

或者你也可以使用类似的工具磨坊主将 CSV 转换为 JSON 等结构化形式,然后使用杰奇来操纵它。

相关内容