簡體   English   中英

如何使用sed刪除匹配的行,上面的行和下面的行?

[英]How do I delete a matching line, the line above and the one below it, using sed?

我在文件中多次出現以下序列:

yyyy
xxxx
zzzz

我有一個匹配xxxx的正則表達式。 每當有匹配時,我想刪除該行,之前的行(例如yyyy )和之后的行(例如zzzz )。 我如何使用sed來做到這一點?

訣竅是存儲在“保留空間”中看到的最后一行。

sed -n '
/^xxxx/{n
        n
        x
        d
       }
x
1d
p
${x
  p
 }
' <input file>

x - 交換當前輸入行與保持空間( x ),然后對於第一行不打印任何東西( 1d ),后續行打印剛剛從保持空間( p )交換的行,在最后一行line再次交換hold空間並打印其中的內容( $x{xp} 。當我們點擊目標行時開始做什么(開始/^xxxx/ ) - 將下兩行讀入模式空間( nn )並將模式空間與保持空間( x )交換 - 這使得我們想要打印的下一行保留空間和匹配前的行的模式空間,這是我們不想要的,所以我們放棄它( d

您可以查看此文檔 它涵蓋了使用sed處理多行。

您可以使用以下內容:

sed -n '/xxxx/{N;s/.*//;x;d;};x;p;${x;p;}'

這將用一個空行代替3行。

你可以先反轉文件,使用sed刪除匹配的行和下一行(或行, sed命令中的+Nd ),最后反轉結果:

tac old.file | sed -e '/xxxx/,+1d' | tac > new.file

這就是我在perl中的表現,也許它可以幫助你找到正確的軌道......祝你好運!

open(INFILE,"<in.txt");
my(@arrayOutBoundData, $skipNextLine)l
for (<INFILE>) {
    if (not $skipNextLine) {
        if (/^xxxx$/) {
            pop(@arrayOutBoundData);
            $skipNextLine = 1;
        } else {
            push(@arrayOutBoundData,$_);
        }
    }
$skipNextLine = 0
}

open(OUTFILE,">out.txt");
for (@arrayOutBoundData) {
    print OUTFILE;
}

(未在此系統上測試過沒有perl請原諒任何現場。)

這可能適合你(GNU sed):

echo -e "a\nyyyy\nxxxx\nzzzz\nb" | sed 'N;/^xxxx/M{/^xxxx/d;$!N;d};P;D'
a
b

這樣可以在模式空間中保留兩行窗口,如果在第一行或第二行中找到所需的正則表達式,則讀取以下行,然后刪除所有三行。 邊緣情況是在前/后沒有行的情況下在第一行或最后一行中找到正則表達式。 在這些情況下,只能刪除兩行。

順便提一下,這個解決方案可能在GNU sed中發現了一個可能的錯誤。 地址的M標志允許^$元字符在regexp中用作多行字符串中行的起點和終點的零長度標記。 空地址//重用先前聲明的地址。 該地址應該是包含多行標志的地址嗎? 目前它似乎包括國旗,即使它沒有說明即

sed 'N;/^xxxx/M{/^xxxx/d;$!N;d};P;D' file

產生不同的(正確的)結果:

sed 'N;/^xxxx/M{//d;$!N;d};P;D' file

如果xxxx出現在文件的第二行。

grep -v -f <(grep -1 "xxxx" file) file

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM