我正在编写一个shell脚本来读取Vagrantfile并引导它(简而言之;))
但我正在用下面的代码撞墙:
TEST=()
while read result; do
TEST+=(`echo ${result}`)
done <<< `awk '/config.vm.define[ \s]\"[a-z]*\"[ \s]do[ \s]\|[a-zA-Z_]*\|/, /end/ { print }' Vagrantfile`
echo "${TEST[1]}"
当我将Vagrant文件传递给这个awk模式正则表达式时,会找到两台定义的机器(config.vm.define)。
输出
config.vm.define "web" do |web|
web.vm.box = "CentOs"
web.vm.box_url = "http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130731.box"
web.vm.hostname = 'dev.local'
web.vm.network :forwarded_port, guest: 90, host: 9090
web.vm.network :private_network, ip: "22.22.22.11"
web.vm.provision :puppet do |puppet|
puppet.manifests_path = "puppet/manifests"
puppet.manifest_file = "web.pp"
puppet.module_path = "puppet/modules"
puppet.options = ["--verbose", "--hiera_config /vagrant/hiera.yaml", "--parser future"]
end
config.vm.define "db" do |db_mysql|
db_mysql.vm.box = "CentOs"
db_mysql.vm.box_url = "http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130731.box"
db_mysql.vm.hostname = 'db.mysql.local'
db_mysql.vm.network :private_network, ip: "22.22.22.22"
db_mysql.vm.network :forwarded_port, guest: 3306, host: 3306
db_mysql.vm.provision :puppet do |puppet|
puppet.manifests_path = "puppet/manifests"
puppet.manifest_file = "db.pp"
puppet.module_path = "puppet/modules"
puppet.options = ["--verbose", "--hiera_config /vagrant/hiera.yaml", "--parser future"]
end
但我似乎无法将它们很好地传递到数组中。我想要的是TEST数组包含两个索引,机器config.vm.define块作为它们的对应值。
E.g。
TEST[0] = 'config.vm.define "web" do |web|
.... [REST OF THE BLOCK CONTENT] ...
end'
TEST[1] = 'config.vm.define "db" do |db_mysql|
.... [REST OF THE BLOCK CONTENT] ...
end'
输出echo "${TEST[1]}"
为nothing
。 echo "${TEST[0]}"
返回上面绘制的整个块。
我玩过IFS / RS / FS,但似乎无法获得我想要的输出。
答案 0 :(得分:2)
解决方案可能是将两个块写入两个单独的文件(blk1
和blk2
),如下所示:
awk '
/config.vm.define[[:space:]]\"[a-z]*\"[[:space:]]do[[:space:]]\|[a-zA-Z_]*\|/{f=1; i++}
f{print $0 > "blk"i}
/end/ {f=0}' Vagrantfile
然后将这两个文件作为
读入bash数组IFS= TEST=( $(cat <"blk1") $(cat <"blk2") )
注意:强>
\s
似乎仅适用于最新版本的gawk
(适用于4.1版本,但不适用于版本3.1.8。gawk
版本3.1.8,请改用[[:space:]]
。gawk
版本4.1,正则表达式\s
在括号[\s]
内不起作用。使用config.vm.define[[:space:]]
或config.vm.define\s
.. <强>更新强>
另一种方法是在块之间插入人工分隔符,例如字符串@@@
。然后你可以做
IFS= TEST=()
while IFS= read -r -d '@' line ; do
TEST+=($line)
done < <(awk '
/config.vm.define[[:space:]]\"[a-z]*\"[[:space:]]do[[:space:]]\|[a-zA-Z_]*\|/{f=1; i++}
f{print }
/end/ {f=0; print "@@@"}' Vagrantfile)