2

考虑这个来源:

field1;field2;"data;data field3";field4;"data;data field5";field6
field1;"data;data field2";field3;field4;field5;"data;data field6"

如您所见,字段分隔符在某些字段内使用,包含在". 我无法直接解析,awk因为无法避免不必要的拆分,至少我还没有找到方法。此外,这些特殊字段在一行内的位置可变,它们可以出现一次、两次、4次等。

我想到了一个涉及预解析步骤的解决方案,我;用某种代码替换这些字段中的。问题是sed/awk执行贪婪REGEX匹配。所以在上面的例子中,我只能;在每行中用引号括起来的最后一个字段内替换。

如何匹配每个引号实例并替换其中的具体实例;?我不想使用perlpython等。

4

2 回答 2

3

使用gnu awk您可以使用特殊FPAT变量为您的字段设置正则表达式。

您可以使用此命令将所有内容替换;|双引号内:

awk -v OFS=';' -v FPAT='"[^"]*"|[^;]*' '{for (i=1; i<=NF; i++) gsub(/;/, "|", $i)} 1' file

field1;field2;"data|data field3";field4;"data|data field5";field6
field1;"data|data field2";field3;field4;field5;"data|data field6"
于 2017-06-13T12:45:24.073 回答
2

作为替代方案,FPAT您可以将 设置awk FS为双引号,然后将分号分隔符换成其他所有字段:

awk -F"\"" '{for(i=1;i<=NF;++i){ if(i%2==0) gsub(/;/, "|", $i)}} {print $0}' yourfile

这里 awk 是:

  1. -F"\""用双引号 ( )分割记录
  2. 循环遍历它找到的每个字段 ( {for(i=1;i<=NF;++i))
  3. if(i%2==0)如果字段序号为 0 ( )则测试字段序号的 mod 2
  4. 如果是偶数,它会用管道 ( gsub(/;/, "|", $i))交换分号
  5. 打印出转换后的记录 ( {print $0})
于 2017-06-13T12:48:06.893 回答