如何保存复杂的正则表达式以在sed中多次重用?


12

在使用时sed,我经常创建相当复杂的正则表达式,我需要在一个文件中进行两次匹配。我有办法保存此正则表达式并仅引用它两次吗?

也许看起来像这样?

sed ' complicated_regex=/^(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+$/
s/complicated_regex:complicated_regex/simple-output/
' my_file

更新:一个答案提出了使用bash变量的解决方案。这行不通。给定一个test.txt

#test.txt
foo bar
bar foo

和脚本

#!/bin/bash

VALUE='foo \([a-z]\+\)'

sed 's/"${VALUE}"/foo happy \1/' test.txt

这应该产生输出

foo happy bar
bar foo

但是我得到了错误

sed: -e expression #1, char 24: invalid reference \1 on `s' command's RHS

如果使用Perl,则可以在表达式中引用表达式的前面部分:perl -pe 's/^(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+:\1$/simple_output/' my_file
glenn jackman 2011年

1
当您发现某些东西对于sed来说太复杂时,请毫不犹豫地选择awk或perl。
吉尔(Gilles)“所以,别再邪恶了”,

2
@Cory:如果正确使用了示例,则示例可以正常工作。您仍然将“ $ variable”括在“单引号”中,将其从您期望的shell扩展中隐藏起来……应该是sed 's/'"${VALUE}"'/foo happy \1/' test.txt
Peter.O 2011年

Answers:


7

您可以使用外壳变量:

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+'
sed s/^"$complicated_regex":"$complicated_regex"\$/'simple-output'/ my_file

我不确定您的意思是什么$i,但您可能需要将其放在单引号之外:

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{'"$i"'}})?)+'

当然,仅当sed从外壳调用命令时,此方法才有效,但是几乎所有编程语言都有类似的解决方案。(而且我认为不可能在中使用变量sed。)
StéphaneGimenez

嗯 尝试此操作,反向引用似乎已损坏。 s/$complicated_regex/\1/给出错误消息,指出该引用无效。
科里·克莱因

嗯,也许是我的错,我已经习惯了zsh变量替换。查看最新答案。
斯特凡希门尼斯

您必须从变量中删除锚,并将其放入sed脚本中:sed "s/^${complicated_regex}:${complicated_regex}\$/simple-output/" my_file
glenn jackman 2011年

h!是的,我忘了检查,我是提供了一个有效的正则表达式串联:-)
斯特凡希门尼斯

0

将shell变量值放入的最简单方法是sed,不必担心在sed脚本的其余部分中反斜杠转义将如何更改,将变量之外的所有内容都放入单引号中,并将其放在双引号中。

以下所有代码示例均假定: VALUE='foo \([a-z]\+\)'

以下破碎的代码失败,因为VALUE未扩展变量:

sed 's/"${VALUE}"/foo happy \1/' test.txt

以下破损的代码失败,因为反斜杠在出现之前\1就被外壳吃掉了(因为它是双引号而不是单引号)sed

sed "s/${VALUE}/foo happy \1/" test.txt

以下代码按预期工作:

sed 's/'"${VALUE}"'/foo happy \1/' test.txt

以下代码也适用:

sed "s/${VALUE}/foo happy \\1/" test.txt

以下内容也是如此:

sed s/"${VALUE}"/foo\ happy\ \\1/ test.txt

但是为什么变得复杂?sed脚本周围的单引号使所有内容都更加清晰,特别是对于非shell脚本专家阅读您的代码而言。同样,我偏爱的方法是,仅出于变量扩展的目的,将单引号删除为双引号,然后再跳回单引号:

sed 's/'"${VALUE}"'/foo happy \1/' test.txt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.