簡體   English   中英

UNIX sed:如果下一行不是數字(或匹配相同的模式),如何刪除帶有模式的行?

[英]UNIX sed: How to remove lines with pattern if next line is not a number(or matches the same pattern)?

這是示例文本文件:

$ cat text.txt
Checking log log0.txt
12
Checking log log1.txt
Checking log log2.txt
34
56
78
Checking log log3.txt
Checking log log4.txt
Checking log log5.txt
90

如何使用sed(或任何其他工具)處理它,因此它看起來像這樣:

$ cat text.txt
Checking log log0.txt
12
Checking log log2.txt
34
56
78
Checking log log5.txt
90

模式是“正在檢查”

更新:如果最后一行具有“檢查”模式,則也應將其刪除。

如果這還不是全部,您需要:

$ awk '/Checking/{p=$0 ORS; next} {printf "%s", p; p=""; print} END{printf "%s", p}' file
Checking log log0.txt
12
Checking log log2.txt
34
56
78
Checking log log5.txt
90

然后編輯您的問題,以包含更真實的示例。

在您的評論中有后續問題,這可能是您想要的:

$ awk '/Checking/{p=$0 ORS; next} {printf "%s", p; p=""; print} END{if (p !~ /Checking/) printf "%s", p}' file

通過在上一行而不是當前行上進行操作,可能有一種沒有重復條件的方法,但是一個問題的2次迭代是我的極限:-)。

使用awk或perl這樣的語言更容易做到這一點,但這是魔術:

sed -e '/[^0-9]/{ h; d; }; H; x; s/[0-9]\\+\\n//g;' text.txt

這里的魔力在於它利用了sed有限的分支和保留空間功能以及一些更深奧的命令。 將其分解為可解釋的部分:

/^[0-9]/ {     # for any line with a non-numeric character...
    h          # replace hold space with the line
    d          # move onto next line of input without printing anything
}
H              # Append the current line (one that is necessarily entirely
               # numeric to the hold space
x              # swap the input & hold space
s/[0-9]\+\n//g # Delete an all numeric value + carriage return
               # from start of the input space
               #
               # Content of input space prints here

使用pcregrep另一個簡單解決方案

$ pcregrep -M "^.*$\n\d+" text.txt 
Checking log log0.txt
12
Checking log log2.txt
34
56
78
Checking log log5.txt
90

如果您喜歡sed:

$ cat test.sed
# If line starts with a number:
/^[0-9]/{
# Exchange hold space and patter space
x
# If line is not empty, print it
/^..*/p
# Exchange again
x
# Print the line
p
# Empty contents of pattern space
s/^.*$//
# Put empty line in hold space
h
}

# If line starts with 'Checking' put it in hold space
/^Checking/h

$ cat test.txt
Checking log log0.txt
12
Checking log log1.txt
Checking log log2.txt
34
56
78
Checking log log3.txt
Checking log log4.txt
Checking log log5.txt
90

$ sed -n -f test.sed test.txt
Checking log log0.txt
12
Checking log log2.txt
34
56
78
Checking log log5.txt
90

您可以利用sed中的保留空間以及exchange(或x[在這里檢查]選項和一些分支(或b ),如下所示,以實現您的目標。

# cat 44876377
Checking log log0.txt
12
Checking log log1.txt
Checking log log2.txt
34
56
78
Checking log log3.txt
Checking log log4.txt
Checking log log5.txt
90
# sed -En '/^Checking/h;/^[0-9]+$/{x;G;:l;p;n;/^[0-9]+$/bl}' 44876377
Checking log log0.txt
12
Checking log log2.txt
34
56
78
Checking log log5.txt
90

注意:盡管我覺得[here]提到的awk方法是最簡單的方法。

GNU grep ,使用-B--before-context選項:

grep --no-group-separator -B 1 '^[0-9]\+$' text.txt

輸出:

Checking log log0.txt
12
Checking log log2.txt
34
56
78
Checking log log5.txt
90
sed 'N;/^[^0-9].*\n[^0-9]/!P;D'

暫無
暫無

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

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