sed——当前面的字符不是某个字符时替换字符串中的字符

sed——当前面的字符不是某个字符时替换字符串中的字符

给定一个包含双引号的字符串(或包含类似字符串的文本行),其中一些双引号前面有反斜杠,sed 替换前面没有反斜杠的双引号的最佳方法是什么与其他字符或字符串?

      original string    'Abc \"NN""xyz\"ddd"ee "ff" \"QQ\"'

      replace non backslash double-quote with percent symbol

           new string    'Abc \"NN%%xyz\"ddd%ee %ff% \"QQ\"'

到目前为止,我发现执行此操作的唯一方法是首先将“反斜杠双引号”组合替换为文本中从未找到且与替换字符或字符串不同的某些唯一字符或字符串,然后替换双引号用所需的替换引号(例如反斜杠双引号,或者为了清楚起见,在本例中使用百分号),然后将唯一的保持字符串更改回其原始反斜杠双引号。因此,该方法需要调用 3 次 sed。

那么有没有更简单的方法来使用 sed 来做到这一点?

答案1

使用GNUsed

$ sed -E ':a;s/(\\")([^\]*)"/\1\2%/;ta' input_file
'Abc \"NN%%xyz\"ddd%ee %ff% \"QQ\"'

答案2

sed -e 's/[\]"/%/g' -e 'y/"%/%"/' -e 's/"/\\"/g'

这首先将每次出现的 替换\"%。然后它会全部交换%"反之亦然。最后,所有剩余的双引号都被转义。

如果字符串%从一开始就不包含任何内容,那么效果是所有未转义的双引号都被替换为%

或者,但使用额外的字符 ,@该字符从一开始就不能出现在数据中:

sed -e 's/[\]"/@/g' -e 'y/"/%/' -e 's/@/\\"/g'

这个变体更清楚地显示了发生的情况,也是您在问题中提出的建议(sed尽管仅使用一次调用):在我们转动未转义的双引号时,我们暂时“隐藏”转义的双引号进入%。完成后,我们恢复它们。

答案3

利用流编辑器-E|-r的扩展正则表达式功能 ( ) GNU sed

问题是检测一个引号字符,该字符在其前面看到偶数个(零也是偶数)反斜杠,然后是非反斜杠字符或行首。

该报价被转换为百分比符号。

双引号的版本。

sed -E -f - <<\eof file
  :a;s/((^|[^\])([\][\])*)"/\1%/g;ta
eof

单引号版本。

sed -E -f - <<\eof file
  :a;s/((^|[^\])([\][\])*)'/\1%/g;ta
eof

相关内容