[英]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.