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