当分隔符是列值的一部分时,计算 Unix 中文件的列数



>我在文件中有以下行:

~Test1~, ~Test2~,,,, ~Test3, Test4~, ~Test5~

这应该解释为 7 列,因为 ~Test3 和 Test4~ 之间的逗号是数据,而不是分隔符。

我想在 unix 中有一个动态脚本,它将根据字段分隔符检查列数 (7(,在本例中为","并忽略一列中存在带逗号的文本。在此过程中可以更换分离器。

我认为 sed 中的解决方案是将分隔符从逗号更改为分号";",这将使输出: ~测试1~;~测试2~;;;;~测试3, 测试4~;~测试5

如果你有一致的csv,没有空格,你可以使用Ed Morton的FPAT方法和GNU awk:

$ echo '~Test1~,~Test2~,,,,~Test3, Test4~,~Test5~' | 
gawk -v FPAT='[^,]*|~[^~]+~' '{for (i=1; i<=NF;i++) print i, "<" $i ">"}'
1 <~Test1~>
2 <~Test2~>
3 <>
4 <>
5 <>
6 <~Test3, Test4~>
7 <~Test5~>

对于您的示例,您可以通过实际捕获然后删除空格和逗号来修改该正则表达式以考虑不一致的间距:

$ echo "~Test1~, ~Test2~,,,, ~Test3, Test4~, ~Test5~" | 
gawk -v FPAT="([ ]?~[^~]+~,?)|([^,]*,)" '{for (i=1; i<=NF;i++) {sub(/,$/,"", $i); sub(/^ /,"",$i); print i, "<" $i ">"}}'
1 <~Test1~>
2 <~Test2~>
3 <>
4 <>
5 <>
6 <~Test3, Test4~>
7 <~Test5~>

由于您的示例在逗号之间确实存在不一致的间距,因此您可以使用 Ruby 的 csv 解析器:

$ ruby -e 'require "csv"
options={:col_sep=>", ", :quote_char=>"~"}
CSV.parse($<, **options){ |r| p r}' <<<    '~Test1~, ~Test2~, , , , ~Test3, Test4~, ~Test5~'
["Test1", "Test2", nil, nil, nil, "Test3, Test4", "Test5"]

最新更新