繁体   English   中英

bash中的sed param替换

[英]sed param substitution in bash

“我是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"

为了便于理解“模式”,我在sed“ s”语句中使用了“:”作为分隔符。 我在Google上看到的一些帖子表明,要获取反向参考词的价值,我应该使用$ \\ 1,但这似乎行不通。

我正在寻找的输出是:

“很酷的价值,这是我的新价值”

整个模式是我要替换的。 抱歉,我没有像原来那样明确。

以上只是测试,看我是否可以进行更换。 最终目的是能够用配置文件中的环境变量(逐行)替换配置文件中的“ <%= @term%>”。

任何帮助,将不胜感激。

您添加了太多的斜杠。 添加它们不会使您更安全。 例如, \\<\\>具有特殊含义,分别代表单词的开头和结尾。

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

sed -e "s/<%= @\([A-Za-z0-9]*\) %>/\1/g"

这应该能够捕获testnew

要管理sed,您也不需要阅读太多内容。 本教程应该足够了: http : //www.grymoire.com/Unix/sed.html

修订问题的答案

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

感谢@HuStmpHrr和@ John1024的帮助。 @HuStmpHrr对于斜杠的滥用是正确的……而@ John1024对于“ sed”不是该工作的正确工具这一事实似乎是正确的。

我发现“ perl”以我想要的方式工作(一位同事发现了这一点)。 我宁愿不使用Perl(只是因为我写了太多糟糕的 Perl代码后就成为了反Perl的顽固者),但是我不知道如何使用环境变量来代替ENTIRE模式。

我想出了以下代码来创建正确的输出。 如果其他人能弄清楚如何用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'

感谢您指出正确方向的指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM