我有一个包含超过 200 万条记录的 CSV,格式如下。
path;name;extension;size;date;user
/foo/;difacs;cgi;3,795;18-07-2011;Unix User\pads
/foo/;difacs.cgi;bak;2,622;03-12-2009;Unix User\pads
/foo/test/kzt/netcdfSample/testing/;zzz;;401;27-07-2006;Unix User\kzt
/foo/test/kzt/netcdfSample/vic_netcdf_popup/;a;txt;1,832;17-02-2006;Unix User\kzt
我需要将路径、名称和扩展名合并到一个格式正确的字段中。
path;size;date;user
/foo/difacs.cgi;3,795;18-07-2011;Unix User\pads
/foo/difacs.cgi;bak;2,622;03-12-2009;Unix User\pads
/foo/test/kzt/netcdfSample/testing/zzz/;401;27-07-2006;Unix User\kzt
/foo/test/kzt/netcdfSample/vic_netcdf_popup/a.txt;1,832;17-02-2006;Unix User\kzt
提前致谢!
答案1
这是 slhck 答案的一个变体,它可以正确处理空的扩展字段(并避免错误地替换可能存在于第二或第三个字段中的点):
sed 's/^\([^;]*\);\([^;]*\)/\1\2/;ta;:a;s/^[^;]\+;;/&/;t;s/;/./' inputfile
没有必要使用第三个捕获组。这个答案在没有它的情况下也可以工作。没有必要对替换命令右侧的点进行转义。
这是我的脚本的解释:
- 捕获前两个字段,不包括分隔它们的分号。
ta;:a
- 如果替换成功,则分支到:a
紧随其后的标签 - 这实际上清除了“成功”标志s/^[^;]\+;;/&/
- 将一串非分号后跟两个分号(连接的第一个和第二个字段后跟一个空的第三个字段)替换为自身 - 这是一个无操作,但它设置了“成功”标志。t
- 如果最后一次替换成功(第三个字段为空),则跳到当前行处理的结束(因为没有指定标签)s/;/./
- 如果我们已经到了这一点(第三个字段是不是空),将分号替换为点。