Sed - 删除一对双引号之间的所有分号

时间:2021-04-07 09:22:28

标签: linux unix sed

我有一个脏的 csv 文件,其中包含带引号的分号行。我正在尝试使用以下命令清除这些分号:

sed -rin 's/(^.*\;.*\;\".*)(\;)(.*\"\;.*$)/\1\3/' file

但不知何故,这并没有删除所有的分号。一些有问题的行如下所示:

;0;"One ▒;)";123; ... ; nth-1column;
;0;"Two ▒;)";456; ... ; nthcolumn;

何时应该清洁它们:

;0;"One ▒)";123; ... ; nth-1column;
;0;"Two ▒)";456; ... ; nthcolumn;

可能存在一些编码问题,但这应该被正则表达式忽略。我只对去掉分号感兴趣,编码在之后处理。

关于如何积极清除双引号中包含的所有分号的任何想法?

2 个答案:

答案 0 :(得分:2)

这可能对你有用(GNU sed):

sed -E ':a;s/^([^"]*("[^;"]*"[^"]*)*"[^";]*);/\1/;ta' file

从包含不在双引号之间的字符和不包含 ; 后跟双引号的带引号的字符串以及既不是双引号也不是半引号的字符的每一行的前面开始进行反向引用冒号。如果下一个字符是分号,则将其删除并重复直到失败,然后打印结果。

另一种选择:

sed -E '/^([^"]*("[^";]*"[^"]*)*"[^";]*);/{s//\n\1/;D}' file

或:

sed -E 's/^([^"]*("[^";]*"[^"]*)*"[^";]*);/\n\1/;T;D' file

编辑:

sed -nE '/^([^"]*("[^";]*"[^"]*)*"[^";]*);/{:a;s//\1/;ta;p}' file

答案 1 :(得分:1)

你可以使用

sed ':a;s/^\(\([^"]*;\?\|"[^";]*";\?\)*"[^";]*\);/\1/;ta' file

an online demo

它是这样工作的:

  • :a - 设置 a 标签
  • ^\(\([^"]*;\?\|"[^";]*";\?\)*"[^";]*\); - 查找:
    • ^ - 字符串的开始
    • \(\([^"]*;\?\|"[^";]*";\?\)*"[^";]*\) - 第 1 组:
      • \([^"]*;\?\|"[^";]*";\?\)* - 零次或多次出现
        • [^"]*;\? - 除 " 之外的零个或多个字符,然后是可选的 ;
        • \| - 或
        • "[^";]*";\? - ",然后是除 "; 之外的零个或多个字符,然后是 ",然后是可选的 ;
      • " - " 字符
      • [^";]* - 除 ;" 之外的零个或多个字符
    • ; - 分号
  • \1 - 替换为第 1 组值
  • ta - 如果有替换,返回到 a 标签位置。
相关问题