shell脚本 - 尴尬提取块将文件从文件中块到数组



我当前正在编写一个读取vagrantfile并引导它的shell脚本(简而言之;))

,但我用以下代码撞到墙:

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]}"

当我将VagrantFile传递到此尴尬模式时,并在其中找到了两台机器(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

,但我似乎不能很好地将它们传递到一个阵列中。我想要的是,测试数组包含两个用计算机config.vm.define块作为相应值的索引。

,例如

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]}"nothingecho "${TEST[0]}"返回上面绘制的整个块。

我玩了IFS/RS/FS,但我似乎无法获得我想要的输出。

解决方案可能是将两个块写入两个单独的文件(blk1blk2)为:

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") )

注意:

  • REGEX s似乎仅适用于最新版本的gawk(可与版本4.1一起使用,但不能使用3.1.8版。
  • 对于gawk版本3.1.8,请改用[[:space:]]
  • 对于gawk版本4.1,Regex s在支架[s]中不起作用。使用config.vm.define[[:space:]]config.vm.defines ..

update

一种替代方法是在块之间插入人造分离器,例如字符串@@@。那你可以做

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) 

相关内容

  • 没有找到相关文章

最新更新