我有大量 CSV 文件,应该对其进行过滤并最终合并、排序并删除重复行。
所以通常来说
sed
和 sort
没什么大不了的,我会用类似的东西来实现这一点......
sed -E -e '/KEYWORD/I d' *.csv | sort -bf -ru -t ',' -k 5
但是我必须注意到,在一列中有 JSON 内容,格式为带有换行符的漂亮打印,这导致
sed
窒息。更不用说 JSON 中的 ,
也使得 sort
不可能,因为 CSV 的列也由 ,
分隔。
幸运的是,我可以知道,除了标题之外,CSV 行以 9 位数字(代表第一列)开头,并以第 5 列中的 ISO 格式日期 (
YYYY-MM-DDTHH:MM:SSZ
) 结尾,该日期应该用于排序。 KEYWORD
出现在第 3 列中(另外还出现在 JSON 部分中),JSON 部分出现在第 4 列中。
不幸的是,我不知道是否可以告诉
sed
和 sort
或其他任何内容来忽略换行符(以及 JSON 部分中的 ,
)并使用正则表达式(如定义)来确定 CSV 行和列。
不一定是
sed
和/或sort
,我很感谢每一个如何实现这一目标的建议!
CSV 文件看起来像这样:
ID,"SHORT, DESCRIPTION",NAME,JSON,TIME
...
123456789,ABC:XYZ,NAME: KEYWORD,"{
""name"": ""keyword"",
""name1"": 0,
""name2"": true,
""name3"": [""value""],
""name4"": {
""name5"": ""keyword""
}
}",2000-01-01T00:00:00Z
...
123456789,"ABC:XYZ, DEF",NAME: NOKEYWORD,"{
""name"": ""nokeyword"",
""name1"": 0,
""name2"": false,
""name3"": [""value1"", ""value2"", ""value3""],
""name4"": {
""name5"": ""nokeyword""
}
}",2000-01-01T01:00:00Z
...
gawk 5.3.1及更高版本可以直接解析csv并可以排序。
因此,您显示的 sed/sort 代码可能会变成这样:
gawk --csv '
NR==1 { print }
FNR==1 { next }
!index(toupper($3),"KEYWORD") { next }
{ rows[$0] = $5 }
END {
PROCINFO["sorted_in"] = "@val_str_desc"
for (row in rows) print row
}
' *.csv
我没有试图弄清楚为什么你给出
-b
(忽略前导空格)和 -f
(忽略大小写)选项进行排序。