我正在使用包含 7 列的多行文本文件 (.csv)。
每行包含“应该”是一个唯一的 id 还有一些日期列,其中一个是“最后修改”日期。
我发现应该是“唯一”的 id 实际上有时会重复,这是我需要通过删除除一个之外的所有来解决的问题。
我在下面有一个使用 gawk 的示例,但是有没有办法使用 gawk、awk 或 grep 等来删除任何重复的行,但“最近”修改的行除外?所以,有一些关于什么去和去的逻辑。
例如,这个 csv 提取有两行。除了一个之外,每个字段都是相同的。身份证号码“相同”意味着它是我的目的的“重复”。
但这两条线并不完全相同。
csv 文件最后(第 7 个)字段中的日期使一个条目比另一个条目更旧。
ID12345,Here is some text,ABCDEFG,7,9,2022-08-18 20:15:00,2022-08-26 17:32:00
ID12345,Here is some text,ABCDEFG,7,9,2022-08-18 20:15:00,2022-09-11 22:15:00
是否可以对文件进行 gawk、cat、grep、cut、awk 等操作,并且:
a) 识别具有重复 ID 的任何事物。b) 仅保留最后一个字段中具有“最新”日期的重复项。
理想情况下,我需要保留第一行,因为它具有正在输入数据库的 csv 的标题。
这就是为什么这几乎可以正常工作的原因:
gawk -i inplace '!a[$0]++' *.csv
它实际上似乎删除了保留一行的重复项,但是它没有逻辑来根据最终字段中最旧的日期值来决定要保留什么。
你能帮忙吗...
假设您只想测试每个文件中的重复项,而不是所有文件中的重复项,并且您不关心保留数据的输入顺序,他将使用任何版本的强制性 POSIX 工具执行您想要的操作,因此它会起作用在任何 Unix 机器上:
例如:
请注意,只有
sort
上面必须一次处理所有输入,其他工具一次只处理 1 行,并且sort
旨在通过使用请求分页等来处理大文件,因此即使您也不太可能遇到内存问题如果您的输入文件很大。如果您确实想保留输入行顺序,那么您可以更改上述内容以应用DSU 成语来做到这一点:
但是
sort
在选择行后确实需要一秒钟才能将输入恢复到原始顺序。如果您真的想在保留输入顺序的同时使用对 GNU awk 的一次调用来完成这一切,那么它会是:
该 gawk 脚本将保留原始输入顺序,但必须将每个输入文件的所有内容读入内存。
使用 GNU awk 的mktime()函数:
请参阅使用 gawk (
PROCINFO["sorted_in"]
) 使用预定义的数组扫描顺序来设置输出时数组的默认 for 循环遍历。结合
sort
_awk
=> 按第七个字段(日期字段)反向排序,即最新条目优先。然后仅打印具有第一个唯一 ID 的行。
注意事项:字符串中的额外逗号;如果相同的 ID 出现相同的日期,则按照反向排序定义的行取行;日期字符串完全不使用前导/填充零或混合格式