没有终结的'使用' s /([\ ^] [^])// g'

时间:2016-08-10 00:27:04

标签: linux bash sed rhel

我试图在我的文件中找到任何插入符号(^),并在它们存在时删除它们和后续字符。我在bash中运行它。

任何时候我尝试运行sed来执行此操作:

sed -i 's/([\^][^])//g' myfile.txt

我收到以下错误:

sed: -e expression #1, char 14: unterminated `s' command

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

[^]部分不是字符类; ]括号是否定字符类的第一个字符,代码正在寻找下一个](将所有)//g视为字符类的一部分)而不是找到结束标记,导致错误。

在肯定的情况下,您可以使用[][]在字符类中查找方括号或方括号。否定版本为[^][]

使用[^]]会停止错误消息 - 然后您需要修复正则表达式以执行您想要的操作。

请注意,默认情况下,括号被解释为括号,而不是分组元字符(您需要\(…\))。事实上,没有必要进行分组,所以从下面的讨论中删除了括号。

当我重新阅读问题时,你的正则表达式的修复程度适度清晰。您正在寻找删除插入符号及其后的下一个字符。这有点模棱两可;如果插入符号位于行的末尾(所以下一个字符是换行符),是否还应删除换行符?我不会假设。我还假设应删除^^;问题是'我文件中的任何插入符号(^),删除它们和后续字符'不说'除非下一个字符也是插入符号'。显然,如果任何一个假设是错误的,那么可以调整正则表达式(尽管换行假设更难以处理,但是相当大的余地)。

sed 's/\^.\{0,1\}//g'

这会在同一行上查找插入符号(避免使用字符类)和下一个字符(如果有的话) - \{0,1\}符号表示前一个表达式的0或1次重​​复。

如果sed的变体支持扩展正则表达式,则可以使用sed -E 's/\^.?//g'(Mac OS X和BSD)或sed -r 's/\^.?//g'(GNU)。

POSIX并不真正支持由插入符号组成的字符类。 [\^]表示法是一个由反斜杠和插入符号组成的字符类('或者插入符号?):

$ echo 'abc\de^Afg' | sed 's/[\^].\{0,1\}//g'
abcefg
$ echo 'abc\de^Afg' | sed 's/\^.\{0,1\}//g'
abc\defg
$ echo 'abc\de^Afg' | sed -E 's/\^.?//g'
abc\defg
$ echo 'abc\de^Afg' | /opt/gnu/bin/sed 's/[\^].\{0,1\}//g'
abcefg
$ echo 'abc\de^Afg' | /opt/gnu/bin/sed 's/\^.\{0,1\}//g'
abc\defg
$ echo 'abc\de^Afg' | /opt/gnu/bin/sed -r 's/\^.?//g'
abc\defg
$

(普通sed是Mac OS X sed; /opt/gnu/bin/sed是GNU sed。)

答案 1 :(得分:3)

表达式[^]尚未完成,因为sed正在使用克拉]后面的^作为否定字符列表,但缺少]({{1}需要的。但是那将与收盘[^]]相匹配,没有你想要的(我相信)。

我认为你打算匹配一颗克拉:]。但你写的(\^)也不会与克拉相匹敌。这将匹配反斜杠[\^]或克拉\

^

但即使这不是你写的:

  

找到任何克拉(^)...并删除它们及后续字符

如果预期的后续字符是任何字符,请使用:$ echo 'abc\def^ghij' abc\def^ghij $ echo 'abc\def^ghij' | sed 's/[\^]//g' abcdefghij
如果后续字符是任何不是克拉的字符,请使用:\^.
或者只是:\^[^\^]

\^[^^]

那是:

$ echo 'ab\cd^^ef^gh' | sed 's/\^[^^]//g'
ab\cd^fh

这就是你要找的东西吗?

答案 2 :(得分:2)

  

在我的文件中找到任何克拉(^)字符,并删除它们和后续字符

我们来看看这个测试文件:

$ cat myfile.txt 
a^2 b^2 c

我相信这可以做你想要的:

$ sed  's/\^.\?//g' myfile.txt
a b c

如您所知,^通常是正则表达式活动字符。我们需要转义它,以便我们可以匹配文字^。在正则表达式中,.匹配任何字符。因此,\^.匹配任何字符后跟的插入符号。正则表达式\^.\?匹配插入符号和后续字符(如果有后续字符)。