2013-06-27 80 views

回答

4
awk '/<!-- start of lyrics -->/,/<!-- end of lyrics -->/' input.txt >> Lyric.csv 

這是從我的"The AWK Programming Language" (1984, p23)副本:

  • 圖案1,圖案2 {語句}
    一系列圖案中的每個輸入線從通過圖案匹配的線匹配1到符合模式2的下一行(含);該報表在每個匹配的 行執行。

    範圍模式不能成爲 任何其他模式的一部分。

要從輸出範圍中排除pattern 1 & pattern 2

awk '/pattern 1/,/pattern 2/ {if ($0 !~ /pattern 1|pattern 2/) print}' input.txt 
+0

嘿,這是真的很酷。我不知道我在「AWK編程語言」的副本中錯過了多少次。 +1打開我的眼睛。我不得不把它放在一個文件中來運行它(shell解釋錯誤?),它包括輸出中的「開始」和「結束」行。 – n0741337

+0

@ n0741337增加了一些解釋。 – captcha

+1

@captcha排除一個模式,你可以縮短它爲 - 'awk'NR == 1,/ pattern 1/{next}/pattern 2 /,0 {next} 1'' –

1

這個腳本應該這樣做:

#!/bin/sh 

awk ' 
/<!-- start of lyrics -->/ { lyrics = 1; next } 
/<!-- end of lyrics -->/ { exit } 
lyrics { print } 
' 

如果你把它script.sh那麼你可以使用它像這樣:

./script.sh <input.txt> lyrics.txt 

這是如何工作的:

  • ​​:如果行結束「模式」匹配,則退出
  • lyrics { print }::如果lyrics變量是如果該行的開始「模式」,然後設定lyrics變量,並跳轉到下一行
  • /<!-- end of lyrics -->/ { exit }匹配設置,打印線
0

這不是完全清楚你的意思是「只保存在中間的信息」,但假設你的意思,你只是要打印的兩個分隔符之間有什麼:

awk '/<!-- start of lyrics -->/{p=1}/<!-- end of lyrics -->{p=0}p{print}0' input.txt 

應該工作。

它基本上根據是否已經看到開始/結束標籤來設置和重置標誌,並且僅當標誌爲非零時纔打印行。

0

sed都和awk支持regex ranges

$ cat ff 
1 
2 
3 
4 
START 
4 
5 
3 
6 
7 
END 
14 
5 
8 

$ awk '/START/,/END/' ff 
START 
4 
5 
3 
6 
7 
END 

$ sed -n '/START/,/END/p' ff 
START 
4 
5 
3 
6 
7 
END 
相關問題