为什么 sed 不能正确解释这个多行模式字符串?

ng.*_*bie 0 sed

我有一个非常大的正则表达式模式字符串,用于从日志文件中删除 INFO 消息。当我像下面这样在一行中使用它时,它工作正常:

sed -r '/([12][[:digit:]]{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][[:digit:]]|3[01]) [[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2},[[:digit:]]{3} INFO)/d' >> $2
Run Code Online (Sandbox Code Playgroud)

但是正如你所看到的,这很难阅读,所以我试着把它放在变量中并将它分成多行。所以我做了以下事情:

regex='/([12][[:digit:]]{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][[:digit:]]|3[01])
 [[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2},[[:digit:]]{3} INFO)/d'

cat copy.out | sed -r $regex >> tmp_log.txt
Run Code Online (Sandbox Code Playgroud)

但我不断收到来自 sed 的错误:

sed: -e expression #1, char 67: unterminated address regex
Run Code Online (Sandbox Code Playgroud)

当我使用 echo 时,正则表达式字符串被打印出来,没有任何换行符。

echo $regex
/([12][[:digit:]]{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][[:digit:]]|3[01]) [[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2},[[:digit:]]{3} INFO)/d
Run Code Online (Sandbox Code Playgroud)

似乎我在这里遗漏了一些非常基本的东西,我做错了什么?

Kus*_*nda 5

通过在sed表达式字符串周围使用双引号,您可以使用普通的换行符将其分成多行:

expression="/([12][[:digit:]]{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][[:digit:]]|3[01]) \
[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2},[[:digit:]]{3} INFO)/d"
Run Code Online (Sandbox Code Playgroud)

\第一行的末尾后面只能有一个换行符,第二行不能以任何多余的字符开头。我将字符串中的空格移到第​​一行,使其看起来是故意的,而不是意外的缩进。

或者,您可以使用两个单引号字符串的连接:

expression='/([12][[:digit:]]{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][[:digit:]]|3[01]) '\
'[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2},[[:digit:]]{3} INFO)/d'
Run Code Online (Sandbox Code Playgroud)

这将为变量分配一个单行字符串expression

然后你会用它作为

sed -E -e "$expression"
Run Code Online (Sandbox Code Playgroud)

在这里,我使用-Ehere 代替了更普遍支持的-ras -E(用于在 中启用扩展的正则表达式sed),并使用-e来告诉sed下一个参数是sed要应用于输入的表达式。该sed表达式本身需要用双引号,因为我们不希望shell执行单词拆分和文件匹配其值。

  • @EdMorton 不,对不起,第二个想法是行不通的。如果您使用单引号,\ 和换行符将作为变量值的一部分结束。如果你想使用单引号,你需要`e='something'\<newline>'something'`(两个连接的字符串,中间有一个文字换行符)。 (2认同)