2012-08-01 57 views
0

我想解析名稱和註釋在一些名稱塊頂部的文件。如果我有像一個文件:使用linux從文本文件中有選擇地解析註釋和值

Art 
Boat 
Road 
Tree 
Street 

# Blah 
Star 
Car 
Sun 

Sock 

# Comm1 
# Comm2 
Stop 
Stick 
# Comm 
Stock 
Dock 

,我想分析這個文件的方式,從而提取以「S」與它們對應的評論的所有名稱。相應的註釋是前面的註釋塊(一行或多行註釋),直到在其之前遇到空白爲止。還有一個註釋塊適用於它後面的所有條目,直到遇到空白或其他註釋塊。所以上面的輸入輸出應該是這樣的:

**Name  Comments** 

Street 
Star  # Blah 
Sun   # Blah 
Sock 
Stop  # Comm1 # Comm2 
Stick  # Comm1 # Comm2 
Stock  # Comm 

任何人都可以提出一個很好的方式去這樣做(最好使用shell)?會真的很感激它。謝謝! PS:我很抱歉,如果我在我的描述中不清楚,仍然是新的。

+1

Linux是一個操作系統。你的意思是「shell腳本」? – Keith 2012-08-01 00:51:35

+0

是的,這就是我的意思.. – user1536435 2012-08-01 00:55:55

回答

1

假設你的空白行不包含空格:

sed -n '/^#/H; /^S/{G; y/\n/ /; p}; /^$/h' input 

的第一個命令(/^#/H)追加當前行(註釋)到保留空間。 下一個命令將保留空間(包含所有累積註釋)附加到當前緩衝區,用一個空格替換所有換行符,然後打印該行。無論何時遇到空白行,最後的命令都會清除保留空間。

EDIT(感謝blahdiblah)

上面正確時沒有在前空白線被檢測到新的註釋塊不會復位累加器。這是醜陋的,但說明如下:

sed -n '/^#/{h; bk}; :j /^S/{G; y/\n/ /; p}; /^$/h; d; :k n; /^#/{ H; bk}; bj;' input 
+0

最後一行的輸出不正確。當它輸出「'Stock#Comm'」時輸出「'Stock#Comm1#Comm2#Comm'」。 – blahdiblah 2012-08-01 22:41:24

+0

請注意,此解決方案假設爲gnu sed,並非所有命令都是標準的。 (例如,某個sed在標籤後需要換行符。) – 2012-10-01 12:36:32

1

下面是一些稍微不雅的awk,沒有工作:

awk '/^$/ {ca=""; cp=""} /^#/ {ca=ca " " $0} /^S/ && ca {cp=ca; ca=""} /^S/ {print $0 " " cp}' <input.txt> output.txt 

有兩家店:評論累加器,ca和評論打印緩衝區,cp

  1. 無論何時遇到空行,都將被清除。
  2. 當遇到註釋行時,它被添加到註釋累加器中。
  3. 當遇到以S開頭的行並且註釋累加器包含內容時,註釋打印緩衝區被設置爲註釋累加器中的任何內容,並且後者被清除。
  4. 當遇到以S開頭的行時,打印後會打印註釋打印緩衝區中的任何內容。

有可能是一種更優雅的方法來做到這一點,而且這無疑存在問題(例如,在沒有評論的情況下在行尾添加空格),但它會讓您開始。