using awk sed to parse update puppet file

房东的猫 提交于 2020-01-14 02:57:18

问题


I have a puppet file with a number of lines of code that has a section that looks like this:

$defaultrepo=myrepo
$defaultbranch=mybranch

gitmod::pullstuff {'othergitcode':
      gitcommit => "b54123be540adrwer3b65872384e0101c5f94c926b81",
      gitorg      => "${defaultrepo}",
      branch    => "${defaultbranch}",
    }

gitmod::pullstuff {'mygitcode':
      gitcommit => "b54123be540adrfer3b65872384e0101c5f94c926b81",
      gitorg      => 'awesomerepo',
      branch    => "master",
    }

It can have any number of blocks that will look similar to the two blocks of code listed above.

I am looking for a way to parse the file and pull out the values as variables then use them to obtain the lastest git commit and update the value. I was thinking of awk and sed in a bash script so that it can do something like this. e.g.

values could be: $gitrepo=mygitcode $gitorg=awesomerepo $gitbranch=master

for i in $(awk "regexto pull out each block from  gitmod::pullstuff \{'whatever': through         to the ending \}" puppetfile.pp);
do
    $gitrepo="sed/awk to pullout git repo"
    $gitorg="sed/awk to pullout git org"
    $gitbranch="sed/awk to pullout git branch"
    $newcommit=git ls-remote https://github.com/$gitorg/$gitrepo.git refs/heads/$gitbranch
    sed -i "replace commit with $newcommit"
done

I am not a developer by trade so please bear with me. Could someone please point out what the general structure should look like. Don't worry about the regex etc I can mess around and figure that out. Just wondering how I can get it so that it treats each "block" it finds individually. For some reason I can't get awk to separate them out properly and it messes up the formatting.

Like I can do something like this:

awk "/gitmod::pullstuff/{a=4}{if(a-->0){print;next}}"

and it will pull out everything I want. What I need is to somehow stick it into a for statement so that I can treat each instance that awk finds as a separate block that I can do stuff too.


回答1:


You can try something like:

awk -f m.awk puppetfile.pp  puppetfile.pp

where m.awk is:

NR==FNR {
    if (/^gitmod/) {
        gitrepo=getRepo()
        getline
        getline
        gitorg=getOrg()
        getline
        branch=getBranch()
        com[++i]=getNewCommit()
    }
    else if (/^\$[[:alnum:]]*=/) {
        vn=getVarName()
        val=getVarValue()
        var[vn]=val
    }
    next
}

/^gitmod/ {
    print
    getline
    sub(/".*"/,"\""com[++j]"\"")
}
{ print }

function getVarValue(a) {
    match($0,/=([[:alnum:]]+)[[:blank:]]*/,a)
    return a[1]
}

function getVarName(a) {
    match($0,/\$([[:alnum:]]+)=/,a)
    return "${"a[1]"}"
}

function getNewCommit(cmd,var) {
    cmd="ls-remote https://github.com/"gitorg"/"gitrepo".git refs/heads/"branch
    cmd |& getline var
    return var
}

function getBranch(a,br) {
    match($0,/"(.*)"/,a)
    br=a[1]
    if (br in var) br=var[br]
    return br
}

function getOrg(a,org) {
    match($0,/"(.*)"/,a)
    org=a[1]
    if (org in var) org=var[org]
    return org
}
function getRepo(a,rep) {
    match($0,/\{"(.*)":/,a)
    rep=a[1]
    if (rep in var) rep=var[rep]
    return rep
}



回答2:


Here is a different take on your problem. If you store all this data in a YAML file :

gits:
  othergitcode:
    gitcommit: "b54123be540adrwer3b65872384e0101c5f94c926b81"
    gitorg:    "myreop",
    branch:    "mybranch",
  mygitcode:
    gitcommit: "b54123be540adrfer3b65872384e0101c5f94c926b81",
    gitorg:    'awesomerepo',
    branch:    "master"

Then you can have it on puppet with something like this:

create_resources('gitmod::pullstuff', hiera('gits'))

And this make it easy to manipulate in any scripting language (except awk, I suppose this answer falls short here ...).



来源:https://stackoverflow.com/questions/20613771/using-awk-sed-to-parse-update-puppet-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!