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

为什么 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

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

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

但我不断从 sed 收到错误:

sed: -e expression #1, char 67: unterminated address regex

当我使用 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

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

答案1

通过在表达式字符串周围使用双引号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"

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

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

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'

这会将单行字符串分配给变量expression

然后你可以用它作为

sed -E -e "$expression"

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

相关内容