我正在 sh 中编写一个脚本:
- 读取配置文件
{{ value_0000 }}
对于检索之间的每个值0000
0000
使用作为参数传递的值执行命令- 替换
{{ value_0000 }}
为输出该命令的
笔记:
value_0000
总是转换为数字,例如0000
- 命令总是相同的,例如
/bin/command <value>
- 我不想编辑当前的配置文件,它可以在内存中运行
例子:
# this is a config file
key: {{ value_12345 }}:hello
something
another_key: return:{{ value_56789 }}/yeah
./run.sh
# this is a config file
key: returned-value:hello
something
another_key: return:another-returned-value2/yeah
我可以从配置文件中检索该值,但需要更多代码才能使其按预期工作。
#!/bin/sh
cat some.conf | while read line
do
echo $line
val="$(grep -o -P '(?<={{ value_).*(?= }})')"
command $val
done
答案1
和perl
:
perl -pe 's(\{\{ value_(\d+) \}\})(`cmd $1`)ge' < some.conf
请注意,这里它是安全的,因为$1
保证它是非空的,并且不包含 shell 语法中的特殊字符(仅数字),甚至perl
在这里绕过 shell。但是,如果您\d+
用其他任何内容更改(一个或多个数字的序列),这将变得危险(例如对于诸如 之类的值foo;reboot
),您可能需要采取更安全的方法,例如:
perl -pe '
s(\{\{ value_(.*?) \}\})(
open my $fh, "-|", "cmd", $1 or die "cannot start cmd: $!";
local $/ = undef;
<$fh>;
)ge' < some.conf
如果cmd
接受选项,您可能需要替换"cmd"
为"cmd", "--"
or qw(cmd --)
(假设它支持--
作为选项结束标记)以避免以-
( 和可能+
) 开头的值出现问题。
任何状况之下,while read
最好避免使用 shell 循环来处理文本。
答案2
使用 GNU awk 将第三个参数匹配到 match():
$ cat tst.awk
match($0,/(.*{{ value_)([0-9]+)( }}.*)/,a) {
cmd = "echo \"<foo_" a[2] "_bar>\""
if ( (cmd | getline output) > 0 ) {
$0 = a[1] output a[3]
}
close(cmd)
}
{ print }
$ awk -f tst.awk some.conf
# this is a config file
key: {{ value_<foo_12345_bar> }}:hello
something
another_key: return:{{ value_<foo_56789_bar> }}/yeah
以及任何 awk:
$ cat tst.awk
match($0,/{{ value_[0-9]+ }}/) {
cmd = "echo \"<foo_" substr($0,RSTART+9,RLENGTH-12) "_bar>\""
if ( (cmd | getline output) > 0 ) {
$0 = substr($0,1,RSTART+8) output substr($0,RSTART+RLENGTH-3)
}
close(cmd)
}
{ print }
$ awk -f tst.awk some.conf
# this is a config file
key: {{ value_<foo_12345_bar> }}:hello
something
another_key: return:{{ value_<foo_56789_bar> }}/yeah