2016-03-04 37 views
3

从文件,我想用awk来提取特定的值:AWK,提取细节值从文件

输入文件:

EVS 58 (EVSTEST1): 
      Export name: /EXPORT1 
      Export path: /opt/export1 
     File system label: fs_test1 
     File system size: 18.7 GB File system free space: 16.5 GB 
     File system state: 
       formatted = Yes 
        mounted = Yes 
        failed = No 
     thin provisioned = No 
     Access snapshots: No 
     Display snapshots: No 
      Read Caching: Disabled Disaster recovery setting: 
     Recovered = No Transfer setting = Use file system default 

    Export configuration: 


EVS 59 (EVSNEXT): 

      Export name: /next 
      Export path: /next 
     File system label: fs_next 
     File system size: 9.75 GB File system free space: 2.28 GB 
     File system state: 
       formatted = Yes 
        mounted = Yes 
        failed = No 
     thin provisioned = No 
     Access snapshots: No 
     Display snapshots: No 
      Read Caching: Disabled Disaster recovery setting: 
     Recovered = No Transfer setting = Use file system default 

    Export configuration: 
10.26.xx.xx(rw,norootsquash) 
10.26.xx.xx(rw,norootsquash) 
10.26.xx.xx(rw,norootsquash) 

我需要提取行: EVS & EVS ID,导出名称,导出路径,文件系统标签和导出配置(如果存在)。

得到以下的输出:

58;EVSTEST1;/EXPORT1;/opt/export1;fs_test1;- 
    59;EVSNEXT;/next;/next;fs_next;10.26.xx.xx(rw,norootsquash);10.26.xx.xx(rw,norootsquash);10.26.xx.xx(rw,norootsquash) 

但是,随着我的脚本波纹管,我不能让所有的“导出配置”线。我只得到了鱼。我试图与for循环,如果一些没有成功..

#!/bin/bash 

LST_NFS=$(cat lst_nfs.txt | awk -F= '\ 
    ($1~/^EVS/) { gsub(/\(/,"");gsub(/\)/,"") ; gsub(/:/,""); split($0,parts," ") ;evsid=parts[2];evsname=parts[3] } 
    ($1~/   Export name/) { split($0,parts," ") ; name=parts[3] } 
    ($1~/   Export path/) { split($0,parts," ") ; path=parts[3] } 
    ($1~/  File system label/) { split($0,parts," ") ; fs=parts[4] } 
    ($1~/ Export configuration:/) { getline; 
     if ($1~ /^[0-9]+/) { export1=$1; getline; 
     printf "%s;%s;%s;%s;%s;%s\n",evsid,evsname,name,path,fs,export1} 
     else { export1="-"; 
       printf "%s;%s;%s;%s;%s;%s\n",evsid,evsname,name,path,fs,export1 } 

    }') 
    echo -e "$LST_NFS" 

我的脚本结果:

57;EVSTEST1;/EXPORT1;/opt/export1;fs_test1;- 
59;EVSNEXT;/next;/next;fs_next;10.26.xx.xx(rw,norootsquash) 

你的帮助非常感谢。

问候,

格雷格

回答

2

当你在输入数据AVE name = value对这是一个好主意,以创建一个name2value数组,然后只是打印任何您喜欢的它的名字:

$ cat tst.awk 
BEGIN { OFS=";" } 

{ gsub(/^[[:space:]]+|[[:space:]]+$/,"") } 

$1=="EVS" { 
    gsub(/[()]/,"") 
    n2v["EVS"] = $2 
    n2v["EVS ID"] = $3 
} 

inEC { 
    if (NF) { 
     n2v[name] = (name in n2v ? n2v[name] OFS : "") $0 
    } 
    else { 
     n2v[name] = (name in n2v ? n2v[name] : "-") 
     prtRec() 
     delete n2v 
     inEC = 0 
    } 
} 
/^Export configuration:/ { sub(/:.*/,""); name=$0; inEC=1 } 

!inEC { 
    name = value = $0 
    sub(/[[:space:]]*:.*/,"",name) 
    sub(/[^:]+:[[:space:]]+/,"",value) 
    n2v[name] = value 
} 

END { prtRec() } 

function prtRec() { 
    print n2v["EVS"], n2v["EVS ID"], n2v["Export name"], n2v["Export path"], \ 
      n2v["File system label"], n2v["Export configuration"] 
} 

$ awk -f tst.awk file 
58;EVSTEST1:;/EXPORT1;/opt/export1;fs_test1;- 
59;EVSNEXT:;/next;/next;fs_next;10.26.xx.xx(rw,norootsquash);10.26.xx.xx(rw,norootsquash);10.26.xx.xx(rw,norootsquash) 
+1

非常感谢埃德! – Indi59

2

awk来救援!

可以写得更好,但适用于您的文件,如果您的格式是标准的。

$ awk -v RS="\n\n\n" -v OFS=';' ' 
    {for(i=1;i<=NF;i++) 
     if($i" "$(i+1)=="Export configuration:") {c=i; break} 
    if(c) for(j=c+2;j<=NF;j++) 
       {e=e sep $j; sep=OFS} 
    else e="-"; 
    sub(/\(/,"",$3);sub(/\):/,"",$3); 
    print $1$2,$3,$6,$13,e; c=0}' file 

EVS58;EVSTEST1;/EXPORT1;fs_test1; 
EVS59;EVSNEXT;/next;fs_next;10.26.xx.xx(rw,norootsquash);10.26.xx.xx(rw,norootsquash);10.26.xx.xx(rw,norootsquash) 

注意,这需要在GAWK多字符记录分隔符,您可以AWK或可能不支持。

+0

非常感谢karakfa! – Indi59

+1

请注意,这不是一个健壮的代码,并取决于字段的位置。 @Ed Morton的解决方案更加强大。关于'awk'的好处之一是编写一次性代码非常容易。 – karakfa