's/([\^][^])//g' 未终止 's' 命令

Unterminated 's' command with 's/([\^][^])//g'

我正在尝试在我的文件中查找任何脱字符 (^) 字符,并在它们存在时删除它们和后续字符。我在 bash.运行 宁此 bash。

任何时候我尝试 运行 sed 这样做:

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

我收到以下错误:

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

有什么想法吗?

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

在肯定的情况下,您可以使用[][] 来查找字符class 中的右方括号或左方括号。否定版本将是 [^][].

使用 [^]] 将停止错误消息 — 然后您只需修复正则表达式即可执行您想要的操作。

请注意,默认情况下,圆括号被解释为圆括号,而不是分组元字符(为此您需要 \(…\))。其实分组是没有必要的,所以括号从下面的讨论中去掉。

当我重新阅读问题时,对你的正则表达式的修复比较清楚。您要删除插入符号及其后的下一个字符。这有点模棱两可;如果插入符在行尾(因此下一个字符是换行符),是否也应该删除换行符?我假设不会。我还假设 ^^ 应该被删除;问题说 'any caret (^) characters in my file, and delete them and the subsequent character' 而没有说 'unless the next character is a caret too'。显然,如果任一假设错误,则可以调整正则表达式(尽管换行假设更难处理,但差距很大)。

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

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

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

POSIX 并不真正支持仅由插入符组成的 class 字符。 [\^] 符号是一个字符 class,由一个反斜杠和一个脱字符组成('or a caret'?):

$ 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。)

find any carat (^) characters in my file, and delete them and the subsequent character

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

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

我相信这会满足您的要求:

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

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

表达式 [^] 未完成,因为 sed 使用克拉 ^ 后面的 ] 作为字符的否定列表,缺少 ] ([^]]) 需要。但这将匹配结束 ],没有你想要的(我相信)。

我相信你的意图是匹配一克拉:\^。但是你写的([\^])也不会匹配克拉。这将匹配反斜杠 \ 或克拉 ^:

$  echo 'abc\def^ghij'
abc\def^ghij

$ echo 'abc\def^ghij' | sed 's/[\^]//g'
abcdefghij

但即使那样也不是你写的:

find any carat (^) ... and delete them and the subsequent character whenever they exist

如果预期的后续字符是任何字符,请使用:\^.
如果后续字符是任何不是克拉的字符,请使用:\^[^\^]
或者简单地说:\^[^^]

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

即:

sed -i 's/\^[^^]//g' infile

这是你要找的吗?