2013-04-11 87 views
4

在Awk中,範圍模式不是表達式,所以canot使用「!」不是。 那麼如何實現它(使用awk打印除了匹配範圍模式以外的所有內容)?打印所有內容使用awk除了匹配範圍模式外

例如

$貓1.T

abd 
hfdh 
# 
fafa 
deafa 
123 
# 
end 

我想要的結果:

貓1.T

abd 
hfdh 
end 

編輯:

我給了一個不恰當的例子。 endpattern應該與startpattern不同,因爲我只是沒有測試過這個。這是我的錯。

同時,我想操作範圍模式和非範圍模式不同。所以sed不是我的選擇。

+1

+1爲您的棘手示例文本! – Kent 2013-04-11 17:32:49

回答

6

你剛剛給了一個棘手的(我不知道應該稱之爲好還是壞^ _ ^)例子。您的文字具有完全相同startpatternendpattern#

我猜你是爲sed '/#/,/#/d'sed -n '/#/,/#/!p'

尋找同樣的方式有一些similiar(不一樣的sed的)地址AWK模型。在手冊頁中有解釋。我說的不一樣,你的榜樣是好的。如果start == end awk的地址模式是行不通的:

kent$ echo "abd 
hfdh 
# 
fafa 
deafa 
123 
# 
end"|awk '/#/,/#/{next}1'                                     
abd 
hfdh 
fafa 
deafa 
123 
end 

因爲AWK同一線路匹配(再次檢查手冊頁),但如果它們是不同的,看下面的例子:

kent$ echo "abd 
hfdh 
# 
fafa 
deafa 
123 
## 
end"|awk '/#/,/##/{next}1' 
abd 
hfdh 
end 

它會給你想要的。所以如果是這樣的話,你可以這樣做:

awk '/start/,/end/{next}1' 

是的,和sed的很相似。

如果開始和結束真的是一樣的,你想用awk做,你需要標誌。

kent$ echo "abd 
hfdh 
# 
fafa 
deafa 
123 
# 
end"|awk '/#/&&!f{f=1;next}f&&/#/{f=0;next}!f' 
abd 
hfdh 
end 

那麼,在例如更好地使用^#$,但這不是重點。我希望這回答了你的問題。

+0

+1對於很好的解釋 – 2013-04-11 17:38:53

+0

'awk'/ start /,/ end/{next} 1''正確和詳細的答案爲我的問題,但我沒有解釋清楚使用這個尷尬的例子! – 2013-04-12 04:18:25

0

是sed的替代方案嗎?

$ sed '/#/,/#/d' input 
abd 
hfdh 
end 
0

如果你確實需要使用awk,這樣的事情應該工作:

awk 'BEGIN{x=1} /startpattern/{x=0} /endpattern/{x=1;next} x{print}' 

雖然sed替代可能是一個更簡單的方法(這減少了擊鍵次數,至少)。

編輯:@Kent指出,你有相同的開始和結束模式,這使得它有點棘手,但這應該工作:

awk 'BEGIN{x=1} /pattern/{x=!x;next} x{print}' 

,每一個看到它的模式時候基本上切換x,並且僅在x!=0時打印。在那裏的next可以避免在重新打印時打印圖案。

+0

這不適用於OP的例子,它有相同的開始和結束模式。您需要檢查'x'不僅用於打印,還用於設置'x'本身。 – Kent 2013-04-11 17:32:01

+0

@Kent good catch ...在考慮到這一點的替代版本中編輯。 – twalberg 2013-04-11 18:17:58