awk:如何将变量用作模式

时间:2018-04-30 13:54:01

标签: bash awk formatting

我的文件格式为:

==============================
nfsserver1.example.com
==============================
/vol/vol1   -sec=sys,rw=clinet1,root=clinet10
/vol/vol2   -sec=sys,rw=clinet1,root=clinet10

==============================
nfsserver3.example.com
==============================

==============================
nfsserver4.example.com
==============================
/vol/vol1   -sec=sys,rw=clinet4,root=clinet10

我需要将其重新格式化为:

nfsserver1.example.com /vol/vol1    -sec=sys,rw=clinet1,root=clinet10
nfsserver1.example.com /vol/vol2    -sec=sys,rw=clinet1,root=clinet10
nfsserver3.example.com
nfsserver4.example.com /vol/vol1    -sec=sys,rw=clinet4,root=clinet10

这就是我的尝试:

while read server; do
    echo "---- ${server} -----------------------------------------"
    cat file.txt|\
        grep -v "========"|\
        awk -v srv=${server} '/^nfsserver1\.example\.com$/ {f=1} f; /^$/ {f=0}'|\
        grep -v "^$"|\
        awk -v srv=${server} '{printf("%s %s\n",srv,$0)}'
    echo
    server=""
done < <(cat file.txt|grep "^[a-z].*\.example\.com$")

但我不知道我是如何将变量合并到模式搜索中的。 我试过这个:

awk -v srv=${server} '$0 ~ srv {f=1} f; /^$/ {f=0}'

但它会产生不正确的输出,我希望与变量完全匹配。

---- nfsserver1.example.com -----------------------------------------
nfsserver1.example.com nfsserver1.example.com
nfsserver1.example.com /vol/vol1    -sec=sys,rw=clinet1,root=clinet10
nfsserver1.example.com /vol/vol2    -sec=sys,rw=clinet1,root=clinet10
nfsserver1.example.com nfsserver1.example.com /vol/vol1 -sec=sys,rw=clinet1,root=clinet10
nfsserver1.example.com nfsserver1.example.com /vol/vol2 -sec=sys,rw=clinet1,root=clinet10
nfsserver1.example.com nfsserver3.example.com
nfsserver1.example.com nfsserver4.example.com /vol/vol1 -sec=sys,rw=clinet4,root=clinet10

---- nfsserver3.example.com -----------------------------------------
nfsserver3.example.com nfsserver3.example.com
nfsserver3.example.com nfsserver3.example.com
nfsserver3.example.com nfsserver4.example.com /vol/vol1 -sec=sys,rw=clinet4,root=clinet10

---- nfsserver4.example.com -----------------------------------------
nfsserver4.example.com nfsserver4.example.com
nfsserver4.example.com /vol/vol1    -sec=sys,rw=clinet4,root=clinet10
nfsserver4.example.com nfsserver4.example.com /vol/vol1 -sec=sys,rw=clinet4,root=clinet10

---- nfsserver3.example.com -----------------------------------------
nfsserver3.example.com nfsserver3.example.com
nfsserver3.example.com nfsserver3.example.com
nfsserver3.example.com nfsserver4.example.com /vol/vol1 -sec=sys,rw=clinet4,root=clinet10

我不需要很多行。我不太确定他们来自哪里。

2 个答案:

答案 0 :(得分:1)

$ awk '
    NF==1 && /[^=]/ { srvr=$0; done=0 }
    NF==2 { print srvr, $0; done=1 }
    !NF && !done { print srvr }
    END{ if (!done) print srvr }
' file
nfsserver1.example.com /vol/vol1   -sec=sys,rw=clinet1,root=clinet10
nfsserver1.example.com /vol/vol2   -sec=sys,rw=clinet1,root=clinet10
nfsserver3.example.com
nfsserver4.example.com /vol/vol1   -sec=sys,rw=clinet4,root=clinet10

您获得的所有额外输出是因为您多次调用awk并因某种原因将调用包装在shell循环中。

答案 1 :(得分:0)

Awk 解决方案:

awk -v RS='==+\n' \
'/^nfsserver/{ k = $1; n = NR + 1 }
 NR == n{ 
     gsub(/^[[:space:]]*|[[:space:]]*$/, "", $0);
     len = split($0, a, "\n");
     if (!len) len = 1;
     for (i=1; i<=len; i++) print k, a[i]
}' file.txt

输出:

nfsserver1.example.com /vol/vol1   -sec=sys,rw=clinet1,root=clinet10
nfsserver1.example.com /vol/vol2   -sec=sys,rw=clinet1,root=clinet10
nfsserver3.example.com 
nfsserver4.example.com /vol/vol1   -sec=sys,rw=clinet4,root=clinet10