bash中的sed param替换

时间:2015-06-11 20:47:00

标签: regex bash shell sed

"我是bash开发和使用sed的新手。我已经尝试了几天,并阅读和搜索了很多关于" sed"我可以。

这是我的问题。我需要更换一行"值"在我正在取代的模式中的术语。我在我的正则表达式中使用反向引用,并且可以在模式中使用术语来替换模式。但是想获得"价值"那个词。

以下是我到目前为止已经开始工作的代码,但无法完成最后一步。

1 #!/bin/bash
2 
3 val='<%= @test %> this is my <%= @new %> here'
4 echo "Echo: $val"
5 
6 export test='cool value'
7 export new='new value'
8 
9 echo $val | sed -e "s:\<\%\= \@\([A-Za-z0-0]*\) \%\>:\1:g"

为了便于理解&#34;模式&#34;,我使用了&#34;:&#34;作为sed&#34; s&#34;中的分隔符声明。我看到的一些谷歌帖子提示,要获得后面参考术语的值,我应该使用$ \ 1,但这似乎不起作用。

我正在寻找的输出是:

&#34;很酷的价值这是我的新价值&#34;

整个模式是我想要替换的模式。对不起,我没有像我原来的帖子那样明确。

以上只是测试我是否可以进行更换。最终目的是能够取代&#39;&lt;%= @ term%&gt;&#39;在配置文件中包含环境变量(逐行)的配置文件中。

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:0)

你添加了太多的斜杠。添加它们不会让你更安全。例如,type="submit" value="Submit"\<具有特殊含义,分别代表单词的开头和结尾。

为实现这一点,它比你想象的要简单得多:

\>

这应该能够捕获sed -e "s/<%= @\([A-Za-z0-9]*\) %>/\1/g" test

管理sed,你也不需要阅读很多东西。本教程应该足够了:http://www.grymoire.com/Unix/sed.html

答案 1 :(得分:0)

回答修订问题

sed不适合这个。您可以在运行脚本之前将shell变量的值替换为sed脚本。但是,在 sed脚本开始运行之后,sed无法动态查看shell变量的值。

shell会做你想做的事:

#!/bin/bash

val='<%= @test %> this is my <%= @new %> here'

test='cool value'
new='new value'

for var in test new
do
    val=${val//<%= @$var %>/${!var}}
done
echo $val

以上产生输出:

cool value this is my new value here

除非有令人信服的理由使用shell变量,否则您可能需要考虑使用bash关联数组。请参阅下文,了解适用于原始问题的示例。

回答原始问题

你想要的并不是与sed功能的完美匹配。 gawk提供对shell环境变量的访问,可以使用它。但是,使用bash的内置参数扩展功能来实现您的目标是相对简单的:

#!/bin/bash

val='<%= @test %> this is my <%= @new %> here'
echo "Echo: $val"

export test='cool value'
export new='new value'

val=${val//@test/$test}
val=${val//@new/$new}

echo $val

以上产生输出:

Echo: <%= @test %> this is my <%= @new %> here
<%= cool value %> this is my <%= new value %> here

替代

如果有很多变量,例如testnew,那么创建一个关联数组来保存它们可能更容易:

#!/bin/bash

val='<%= @test %> this is my <%= @new %> here'
echo "Echo: $val"

declare -A arr=([test]='cool value' [new]='new value')

for key in "${!arr[@]}"
do
    val=${val//@$key/${arr[$key]}}
done

echo $val

以上产生输出:

Echo: <%= @test %> this is my <%= @new %> here
<%= cool value %> this is my <%= new value %> here

答案 2 :(得分:0)

感谢@HuStmpHrr和@ John1024的帮助。 @HuStmpHrr关于滥用斜线的说法是正确的...... @ John1024似乎对“sed”不适合这项工作的事实是正确的。

我发现“perl”按照我想要的方式工作(一位同事想出了这个)。我宁愿不使用perl(仅仅因为我写了太多糟糕 perl代码的时候我是一个反perl bigot),但我无法弄清楚如何获得环境变量来代替整个模式。

我想出了以下代码来创建正确的输出。如果其他人可以在sed或awk中找出如何做到这一点,我将不胜感激。

1 #!/bin/bash
2 
3 pat="<%= *@([a-zA-Z0-9_]*) *%>"
4 val='<%= @test %> this is my <%= @new %> here'
5 echo "Echo: $val"
6 
7 export test='cool value'
8 export new='new value'
9 
10 # this is the old attempt with sed. It didn't produce output I wanted
11  echo $val | sed -e 's/<%= @\([A-Za-z0-9]*\) %>/\1/g'
12 
13 # this works the way I want to with Perl
14  echo $val | perl -pe 's/<%= *@([a-zA-Z0-9_]*) *%>/$ENV{$1}/g'

感谢正确方向的指示。