尝试使用sed替换不会出现在字符串开头或结尾的标点符号

时间:2016-01-26 06:35:39

标签: bash sed

sed -i '/^'/! /$'/! s/'/\''/g' binfile.new

此代码的目的是,如果我有以下行:

'Here is Jay's House'

它会将其转换为

'Here is Jay''s House'

我无法弄清楚语法 - 有什么帮助?

2 个答案:

答案 0 :(得分:2)

对于示例输入,最简单的技术是:

sed -e "s/'/''/g" -e "s/^''/'/" -e "s/''$/'/"

用两个单引号替换每个单引号;用一个单引号替换前导对;用一个单引号替换尾随对。

这假定字符串作为一个整体从一开始开始到一行的结尾。如果它只覆盖部分线路,你必须更加努力,但问题应该显示真实的输入和输出。

sed -e "s/'/''/g" -e "s/^\([^']*\)''/\1'/" -e "s/''\([^']*\)$/'\1/"

用两个单引号替换每个单引号。在行的开头捕获零个或多个非引号,后跟两个单引号;将其替换为捕获的内容加上一个单引号。在行尾捕获两个单引号,后跟零或多个非引号;用一个单引号和捕获的内容替换它。

通常,我在正则表达式周围使用单引号。但是,当你在正则表达式中使用单引号(而不是双引号)时,在正则表达式周围使用双引号变得更简单,但你必须担心shell将对双引号正则表达式做什么。这一次,没有问题;它并不总是那么简单。如有疑问,请在正则表达式周围使用单引号,并使用字符序列'\''将单引号嵌入字符串的中间位置:

sed -e 's/'\''/'\'''\''/g' -e 's/^\([^'\'']*\)'\'''\''/\1'\''/' -e 's/'\'''\''\([^'\'']*\)$/'\''\1/'

(我有一个程序从带有双引号的版本生成该输出。当有两个相邻的单引号时,人可能会优化它;当发生这种情况时,这会输出两个不必要的单引号。)

答案 1 :(得分:0)

将sed脚本放在一个单独的文件中:假设我们知道字符串两端都会有'

$ sed -rf sedscr <<< "'Here is Jay's House'"
'Here is Jay''s House'

其中sedscr

s/^'(.*)'$/\1/  # Extract part between single quotes
s/'/''/g        # Replace all single quotes with two single quotes
s/(.*)/'\1'/    # Add single quotes at beginning and end back

对于文本中间的单引号字符串:

# Copy pattern space to hold space
h

# Extract substring between single quotes
s/[^']*'(.*)'[^']*/\1/

# Replace single quote with two each
s/'/''/g

# Append hold space to pattern space
G

# Replace part between single quotes
s/(.*)\n([^']*').*('[^']*).*$/\2\1\3/

结果如

$ sed -rf sedscr.sed <<< "Text before 'Here is Jay's House' text after"
Text before 'Here is Jay''s House' text after