2014-01-15 40 views
3

我會喜歡刪除含有另一個指定模式(方便地在新行)模式的所有實例:刪除包含另一種模式多模式

MID: 

樣品輸入:

header 
BEGIN: 
1abc 
7wurw 
END: 
BEGIN: 
22xyz 
MID: 
34utov 
END: 

期望的輸出:

header 
BEGIN: 
1abc 
7wurw 
END: 

我正在尋找可能的一個襯墊。任何幫助,將不勝感激。

回答

4

使用GNU sed

sed -e :a -e '/^BEGIN:/,/^END:/ { /END:/!{$!{N;ba};};/MID:/d;}' inputfile 

爲了您的INP UT,它會返回:

header 
BEGIN: 
1abc 
7wurw 
END: 
+0

輝煌!謝謝<3我的機器上有我的開箱BSD sed出錯,但是在GNU sed中它正在按預期工作 – okapiho

+0

@okapiho對不起,我應該使用GNU sed添加。 – devnull

1
BEGIN { in_block = 0; } 
/BEGIN:/ { in_block = 1; lineno = 0; arr[lineno] = $0; must_write = 1; next; } 
/END:/ { in_block = 0; 
     if (must_write == 1) { 
       for (i = 0; i <= lineno; ++i) print arr[i]; print; 
     } 
     next; 
} 
/MID:/ { must_write = 0; next; } 
in_block == 1 && must_write == 1 { lineno++; arr[lineno] = $0; next; } 
in_block == 0 { print } 

這應該工作(使用提供的測試用例)。一些awk嚮導可能會找到更密集的解決方案。但是您也可以將這種處理用於其他任務。

2

我會使用RS, ORS變量。這裏是一個班輪:

awk -v RS="BEGIN:\n" -v ORS="" '/MID/{next}NR>1{printf RS}7' file 

測試你的文件:

kent$ cat f 
header 
BEGIN: 
1abc 
7wurw 
END: 
BEGIN: 
22xyz 
MID: 
34utov 
END: 

kent$ awk -v RS="BEGIN:\n" -v ORS="" '/MID/{next}NR>1{printf RS}7' f 
header 
BEGIN: 
1abc 
7wurw 
END: 

筆記,printf RS是不是很漂亮,我用它,因爲我知道這是BEGIN:好的做法是printf "%s", RS

+0

不錯:-)但有什麼「7」的含義在最後? – Ronald

+1

@羅納德7等於42這裏;) – hek2mgl

+0

@ hek2mgl所以我發現了,但我不知道這個語法結構。由於我發現了零但打印整個「線」。所以我想它是這樣的:一個表達式評估爲真(數字非零)和默認行爲(打印)。正確? – Ronald

2

這爲我工作的樣品:

sed '/BEGIN:/,/END:/{/BEGIN/{h;d};H;/END:/!d;x;/MID:/d}' input.txt 

我敢肯定它可以簡化很多。

0

gnu awk除以該END:所以它不是真實的BEGIN:節 - END:,但工程:

awk '!/MID:/{printf "%s%s\n",$0,RT}' RS="END:" t 
header 
BEGIN: 
1abc 
7wurw 
END: 
0
sed -n '/BEGIN:/,/END:/ { 
    H 
    /END:/ { 
     s/.*// 
     x 
     /\nMID:/ !p 
     } 
    }' YourFile 

對於OneLiner

sed -n '/BEGIN:/,/END:/{H;/END/{s/.*//;x;/\nMID:/ !p;};}' YourFile 

不會與過去的工作; (我要保持我的AIX一個 「\ n」)(應該在GNU工作SED)

#for AIX 
sed -n '/BEGIN:/,/END:/{H;/END/{s/.*//;x;/\nMID:/ !p;} 
}' YourFile 
1

這可能會爲你工作(GNU SED):

sed '/^BEGIN:/{:a;$!{N;/END:/!ba};/MID:/d}' file