如何使用sed,awk或类似方法在搜索上面的几行中添加信息

时间:2017-06-29 11:31:02

标签: awk sed

使用sed,awk或类似的 我有一个像下面这样的file.xml,我想把mytag的值放到tagxpto之前

    <tagxpto field= />
    <tag1>
    <tag2>
    <mytag value="SUB1-SUB2" />
    <tagxpto field= />
    <tag1>
    <tag2>
    <mytag value="SUB3-SUB4" />
    <tagxpto field= />
    <tag1>
    <tag2>
    <mytag value="SUB5-SUB6" />
    [..]

预期:

    <tagxpto field="SUB1-SUB2" />
    <tag1>
    <tag2>
    <mytag value="SUB1-SUB2" />
    <tagxpto field=SUB3-SUB4 />
    <tag1>
    <tag2>
    <mytag value="SUB3-SUB4" />
    <tagxpto field=SUB5-SUB6 />
    <tag1>    
    <tag2>    
    <mytag value="SUB5-SUB6" /> 
    [..]

你能帮我怎么做这个任务吗?

3 个答案:

答案 0 :(得分:0)

这可能适合你(GNU sed):

sed -r '/tagxpto/{:a;N;/mytag/!ba;s/=(.*("[^"]*"))/=\2\1/}' file

tagxpto收集行到mytag,然后使用反向引用替换所需的字符串。

答案 1 :(得分:0)

使用GNU awk为第3个arg匹配():

$ cat tst.awk
NR==FNR {
    if ( match($0,/^\s*<mytag\s*value=("[^"]*")/,a) ) {
        tags[++myCnt] = a[1]
    }
    next
}
match($0,/^(\s*<tagxpto\s*field=)(.*\/>)/,a) {
    $0 = a[1] tags[++xptoCnt] a[2]
}
{ print }

$ awk -f tst.awk file file
    <tagxpto field="SUB1-SUB2" />
    <tag1>
    <tag2>
    <mytag value="SUB1-SUB2" />
    <tagxpto field="SUB3-SUB4" />
    <tag1>
    <tag2>
    <mytag value="SUB3-SUB4" />
    <tagxpto field="SUB5-SUB6" />
    <tag1>
    <tag2>
    <mytag value="SUB5-SUB6" />

请注意,您发布的预期输出有时会在引号中添加字段,有时并不会解释何时包含引号,如果不是,所以我假设您总是希望它在引号中,如果您不这样做,这是一个微不足道的调整不,比如说将捕获组("[^"]*")更改为"([^"]*)"

答案 2 :(得分:0)

使用awk再试一次方法,只读一次Input_file。

awk '/<tagxpto field/ && val2{sub(/= /,"="val2,val1);print val1 ORS val;val1=$0;val=val2=""} NR==1{val1=$0;next} {val=val?val ORS $0:$0} /<mytag value/{match($0,/".*"/);val2=substr($0,RSTART,RLENGTH)} END{sub(/= /,"="val2,val1);print val1 ORS val}'   Input_file

也会在某段时间内添加它的非单行形式和解释。

编辑:此处也添加非单线形式的解决方案。

awk '/<tagxpto field/ && val2{
                                sub(/= /,"="val2,val1);
                                print val1 ORS val;
                                val1=$0;
                                val=val2=""
                             }
    NR==1{
                val1=$0;
                next
         }
         {
                val=val?val ORS $0:$0
         }
    /<mytag value/{
                        match($0,/".*"/);
                        val2=substr($0,RSTART,RLENGTH)
                  }
    END{
        sub(/= /,"="val2,val1);
        print val1 ORS val
       }
    '    Input_file