![需要 awk/sed 来替换 ${} 中存在的值](https://linux22.com/image/138092/%E9%9C%80%E8%A6%81%20awk%2Fsed%20%E6%9D%A5%E6%9B%BF%E6%8D%A2%20%24%7B%7D%20%E4%B8%AD%E5%AD%98%E5%9C%A8%E7%9A%84%E5%80%BC.png)
我试图通过从 env.properties 文件中获取值来进行 url 测试。
例如,我的 env.properties 看起来像这样
a.host.name=wanx.com
b.host.name=xyu.com
c.host.name=${b.host.name}
d.host.name=${c.host.name}
url1=https://${d.host.name}/test
url2=https://${a.host.name}/test2
到目前为止我所做的 - 1.因为有一个“。”在文件中我无法进行直接替换。所以我使用 awk 用下划线替换了点
awk -F= -vOFS="=" 'gsub(/\./,"_",$1)+1' endpoint_test.txt
现在我的文件如下所示 -
a_host_name=wanx.com
b_host_name=xyu.com
c_host_name=${b.host.name}
d_host_name=${c.host.name}
url1=https://${d.host.name}/test
url2=https://${a.host.name}/test2
我试图替换 ${b.host.name} 和 ${c.host.name} 中存在的值,我已经尝试了从谷歌找到的大多数 awk 命令。以下是我尝试过的命令
awk -F= -vOFS="${#*}" 'gsub(/\./,"_",$1)+1' endpoint_test2.txt
awk -F\" '{OFS="\""; for (i = 2; i < NF; i += 2) gsub(/[$,]/,"",$i); gsub(/"/,""); print}' endpoint_test2.txt
但这不起作用。我想将 ${value} 中的点更改为下划线。因此,如果我将这些内容移动到 shell 中,我就可以很容易地进行替换。
编辑 #1 -
最终我需要一个如下所示的输出文件 -
a_host_name=wanx.com
b_host_name=xyu.com
c_host_name=${b.host.name}
d_host_name=${c.host.name}
url1=https://${d_host_name}/test
url2=https://${a_host_name}/test2
因此,如果我将此文件转换为 shell,我将这样做
a_host_name=wanx.com
b_host_name=xyu.com
c_host_name=${b_host_name}
d_host_name=${c_host_name}
url1=https://${d_host_name}/test
url2=https://${a_host_name}/test2
echo $url1
echo $url2
该文件的输出 -
https://xyu.com/test
https://wanx.com/test2
编辑 #2 - 我尝试了直接 bash,但它说是不好的替换,因为我需要替换 ${} 中的值。
编辑 #3 -
我正在尝试的操作系统位于 AIX 中,并且该文件可能不包含与“a.host.name”相同的变量作为变量。它还可能包含诸如“a.name.host”之类的变量,例如文件可能如下所示 -
a.b.host=qwel.wanx.net
b.host.name=ioy.xyu.net
c.xcv.host=poiu.deolite.net
d.host.name=${b.host.name}
e.host.name=${c.host.name}
abcv.stub.url=https://${d.host.name}/test
xcm.stub.url=https://${a.b.host}/test2
通过这个命令,我能够实现我在编辑 #3 中提到的边缘情况 -
perl -pe 's/^[\w.]+(?==)|\$\{[\w.]+\}/ $_ = $&; tr|.|_|; $_ /ge' file
现在我的输出看起来像这样 -
a_b_host=qwel.wanx.net
b_host_name=ioy.xyu.net
c_xcv_host=poiu.deolite.net
d_host_name=${b_host_name}
e_host_name=${c_host_name}
abcv_stub_url=https://${d_host_name}/test
xcm_stub_url=https://${a_b_host}/test2
最后我需要将 url 单独放在一个单独的文件中,如下所示
https://ioy.xyu.net/test
https://qwel.wanx.net/test2
答案1
你可以这样做:
perl -pe 's/^[\w.]+(?==)|\$\{[\w.]+\}/$& =~ y|.|_|r/ge' < file
即替换.
为_
on 单词字符序列或.
位于行开头且后跟=
或 的内部${...}
。
r
运算符的标志(y///
因此返回替换结果而不是应用于变量)需要 perl 5.14 或更高版本。对于旧版本,您始终可以执行以下操作:
perl -pe 's/^[\w.]+(?==)|\$\{[\w.]+\}/$_ = $&; y|.|_|; $_/ge' < file
perl
现在,对于您的最终任务,在这里完成整个事情就像在 shell 中解释代码一样容易,这将是非常危险的:
perl -lne '
s/\$\{([\w.]+)\}/$v{$1}/g;
if (/^([\w.]+)=(.*)/) {
$v{$1} = $v = $2;
print $v if $1 =~ /_url$/
}' < file > separate-file
答案2
你可以这样尝试:
cat get_env_properties.sh
sed -i'.bak' '
:A
s/\(.*\)\(\.\)\([^=]*=.*\)/\1_\3/
tA
:B
s/\([^{]*{.*\)\(\.\)\([^}]*}.*\)/\1_\3/
tB
' "$1"
. "$1"
echo "url1 = $url1"
echo "url2 = $url2"
mv "$1.bak" "$1"
你这样称呼它
./get_env_properties.sh env.properties
你的 sed 必须可以使用 -i
答案3
如果您所说的“此文件的输出”是您最终想要的结果,请尝试
awk -F= '
{gsub (/[${}]/, "")
}
!/^url/ {T[$1]=($2 in T)?T[$2]:$2
next
}
{sub (/^url[^=]*=/, "")
for (t in T) if ($0 ~ t) sub (t, T[t])
}
1
' file
https://xyu.com/test
https://wanx.com/test2
答案4
尝试这个,
sed -e 's/\./_/g' -e '/com/ s/_/\./3g' test789
a_host_name=wanx.com
b_host_name=xyu.com
c_host_name=${b_host_name}
d_host_name=${c_host_name}
url1=https://${d_host_name}/test
url2=https://${a_host_name}/test2
- 首先 sed 将全部替换
.
为_
_
如果.
该行有,第二个 sed 将替换第三个com