awk - 解析字段中具有与定界符相同字符的文本
awk - parse text having same character in fields as delimiter
考虑这个来源:
field1;field2;"data;data field3";field4;"data;data field5";field6
field1;"data;data field2";field3;field4;field5;"data;data field6"
如您所见,字段定界符被用在某些字段中,包含在 "
之间。我不能直接用 awk
解析,因为没有办法避免不必要的分裂,至少我还没有找到办法。此外,这些特殊字段在一行中的位置可变,可以出现一次、两次、四次等
我想到了一个涉及预解析步骤的解决方案,我将这些字段中的 ;
替换为某种代码。问题是 sed
/ awk
执行贪婪 REGEX
匹配。所以在上面的例子中,我只能在每行用引号括起来的最后一个字段中替换 ;
。
如何匹配引号的每个实例并替换其中的特定 ;
?我不想使用 perl
或 python
等
使用 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"
作为 FPAT
的替代方法,您可以将 awk
FS
设置为双引号,然后将分号分隔符换成其他所有字段:
awk -F"\"" '{for(i=1;i<=NF;++i){ if(i%2==0) gsub(/;/, "|", $i)}} {print [=10=]}' yourfile
这里的awk是:
- 用双引号分割记录(
-F"\""
)
- 遍历找到的每个字段 (
{for(i=1;i<=NF;++i)
)
- 测试字段序号的 mod 2 是否为 0 (
if(i%2==0)
)
- 如果是偶数,则用竖线替换分号 (
gsub(/;/, "|", $i)
)
- 打印出转换后的记录 (
{print [=18=]}
)
考虑这个来源:
field1;field2;"data;data field3";field4;"data;data field5";field6
field1;"data;data field2";field3;field4;field5;"data;data field6"
如您所见,字段定界符被用在某些字段中,包含在 "
之间。我不能直接用 awk
解析,因为没有办法避免不必要的分裂,至少我还没有找到办法。此外,这些特殊字段在一行中的位置可变,可以出现一次、两次、四次等
我想到了一个涉及预解析步骤的解决方案,我将这些字段中的 ;
替换为某种代码。问题是 sed
/ awk
执行贪婪 REGEX
匹配。所以在上面的例子中,我只能在每行用引号括起来的最后一个字段中替换 ;
。
如何匹配引号的每个实例并替换其中的特定 ;
?我不想使用 perl
或 python
等
使用 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"
作为 FPAT
的替代方法,您可以将 awk
FS
设置为双引号,然后将分号分隔符换成其他所有字段:
awk -F"\"" '{for(i=1;i<=NF;++i){ if(i%2==0) gsub(/;/, "|", $i)}} {print [=10=]}' yourfile
这里的awk是:
- 用双引号分割记录(
-F"\""
) - 遍历找到的每个字段 (
{for(i=1;i<=NF;++i)
) - 测试字段序号的 mod 2 是否为 0 (
if(i%2==0)
) - 如果是偶数,则用竖线替换分号 (
gsub(/;/, "|", $i)
) - 打印出转换后的记录 (
{print [=18=]}
)