2016-03-04 93 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