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

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

在使用中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

答案1

您可以使用 shell 变量:

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"'}})?)+'

答案2

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

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

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

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

下列破碎的代码失败,因为反斜杠在看到它\1之前就被 shell 吃掉了(因为它在双引号中而不是单引号中)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

相关内容