2014-05-13 28 views
0

我看到一個複雜的文本文件,其中包含大約300個條目。 我不知道如何去解析這個文件來獲得我想要的輸出。 我的每個網絡用戶在文件中都有一個條目。在Bash中使用數組和Sed以及Awk解析文本文件

USER:martha 
USER:Othello 
USER:darwin 

再下面,是我需要信息的主機文件中的每一用戶項,但一個用戶可以有一個入口,另一個可得:所以在文本文件中,每個用戶名稱開頭多個條目。下面是3個這樣的條目

USER:martha 
    POSITION: 170.198.82.13 [VLT(304394),PT(FULL)] 
      CLIENT: jcrm19.1.p2ps -258- 
      ACCESSPOINT: 170.198.82.13/net 
      APPLICATION: 91 

USER:othello 
    POSITION: 170.198.80.212 [VLT(307571),PT(FULL)] 
      CLIENT: jcrm15.1.p2ps -258- 
      ACCESSPOINT: 170.198.80.212/net 
      APPLICATION: 256 

      CLIENT: jcrm15.1.p2ps -258- 
      ACCESSPOINT: 170.198.80.212/net 
      APPLICATION: 256 

    POSITION: 170.198.80.209 [VLT(306561),PT(FULL)] 
      CLIENT: jcrm14.1.p2ps -258- 
      ACCESSPOINT: 170.198.80.209/net 
      APPLICATION: 256 

      CLIENT: pwrm14.1.p2ps -258- 
      ACCESSPOINT: 170.198.80.209/net 
      APPLICATION: 256 

      CLIENT: pwrm14.1.p2ps -258- 
      ACCESSPOINT: 170.198.80.209/net 
      APPLICATION: 256 


USER:darwin 
    POSITION: 170.198.19.102 [VLT(297987),PT(FULL)] 
      CLIENT: jcrm16.1.p2ps -258- 
      ACCESSPOINT: 170.198.19.102/net 
      APPLICATION: 91 

最終的輸出應如下的例子:

USER  Position   Client  Application 

Martha  170.198.82.13  jcrm19  91 
Othello  170.198.80.212  jcrm15  256 
Othello  170.198.80.209  jcrm14  256 
Martin  170.198.19.102  jcrm16  91 

我有數組的一些經驗,我可以用grep出一些信息,並分配給變量,打印它們。但我不知道如何將信息讀入陣列,作爲每個「USER」下的條目,因爲它們具有不同的長度和內容。

所以我怎麼讀用戶:martha然後跳轉到用戶:othello?此外,在用戶:othello有兩個「位置」,我需要抓住。我只是不知道如何把我正在尋找的內容放入數組變量或常規變量中。我從來不必解析每次使用時長度和內容數據不同的文件。不知道在我開始閱讀和爲下一個用戶分配數值或值之前,我必須閱讀多少行>能否提供一些提示或可能是我可以從頭開始的一段代碼?

感謝

回答

0

我沒有得到我的Mac出手,所以這是未經測試...

awk -F: '/^USER:/{u=$2} /POSITION:/{p=$2} /CLIENT:/{c=$2} /APPLICATION:/{print u,p,c,$2}' yourfile 
+0

OP只是想用'POSITION'來選擇塊,你打印每個塊的條目 – Kent

+0

@Kent哦,是的,你說得對,謝謝。我會讓他選擇你和anubhava的答案。 –

+0

嗨馬克。我試過你的班輪,工作很好。不知道它如何工作,但它的工作原理。所以謝謝。我真的必須瞭解這個職位的工作原理。當我將它與原始日誌文件進行對比時,它也生成了額外的數據列......但這很好。/ – theuniverseisflat

2

使用awkcolumn

awk -F '[: ]+' 'BEGIN{print "USER", "Position", "Client", "Application"} 
    $1=="USER"{u=$2} $2=="POSITION"{p=$3}$2=="CLIENT"{c=$3} 
    $2=="APPLICATION"&&p{print u, p, c, $3; p=""}' file | column -t 

USER  Position  Client   Application 
martha 170.198.82.13 jcrm19.1.p2ps 91 
othello 170.198.80.212 jcrm15.1.p2ps 256 
othello 170.198.80.209 jcrm14.1.p2ps 256 
darwin 170.198.19.102 jcrm16.1.p2ps 91 
+0

這假設領域始終處於樣品中的順序。這可能是正確的,但應該指出。 –

+0

嗨thx ..我試過這個。是的,這些字段總是按照這個順序。它適用於我提供的示例,而不是與我擁有的文本文件。不知道爲什麼。我必須再次查看日誌文件。 Thx快速響應。將不得不看晚,因爲我必須跑再次趕上火車thx! anubhava – theuniverseisflat

+0

當然,讓我知道你是否需要進一步的幫助。 – anubhava

0
awk -v RS="" -F'[:\n ]*' '/^USER/{u=$2} 
/POSI/{p=/^USER/?$4:$3 
for(i=1;i<=NF;i++) 
    if($i=="CLIENT"){sub(/\..*/,"",$(i+1)) 
         print u,p,$(i+1),$NF;break}}' file 

輸出,而不標題:

martha 170.198.82.13 jcrm19 91 
othello 170.198.80.212 jcrm15 256 
othello 170.198.80.209 jcrm14 256 
darwin 170.198.19.102 jcrm16 91 

您可以添加標題和管column -t,以獲得更好的格式

+0

嗨,肯特。感謝您的回覆。對不起,我從來沒有讀過這篇文章。我試過我們的代碼,它什麼都不做。它不會產生錯誤,並且不會產生任何輸出? – theuniverseisflat