我有一个像这样的文本文件:
<!--START OF FILE -->
random text
<meta> more random text </meta>
x x x x x x x
more random text
that I dont need
x x x x x x x
I need everything
from this point
onwards
...
我需要删除<!--START OF FILE -->
第二个和第二个 之间的所有内容x x x x x x x
,如下所示:
I need everything
from this point
onwards
...
我尝试使用sed '/<!--START OF FILE -->/,/x x x x x x x/d' test.txt
,但这消除了第一次出现之间的障碍,x x x x x x x
这不是我想要的。
答案1
这恰恰相反
和sed
你一起做类似的事情:
sed -n '/PATTERN1/,$!{ # if not in this range
p;d # print and delete
}
/PATTERN2/!d # delete if it doesn't match PATTERN2
x;//!d # exchange and then, again, delete if no match
: do # label "do" (executed only after the 2nd match)
n;p # get the next line and print
b do' infile # go to label "do"
或者,在一行中(在gnu
设置上):
sed -n '/PATTERN1/,$!{p;d;};/PATTERN2/!d;x;//!d;: do;n;p;b do' infile
当然,使用 和 计数器更容易awk
。我会把它留给你作为练习......
答案2
简单明了awk
:
$ awk '/<!--START OF FILE -->/ {a=2}; !a; /x x x x x x x/ && a {a--}' < data
I need everything
from this point
...
它只是在a
0 时打印,并在看到 时递减x x x ...
。
或者从文件的实际开头而不是模式开始,将第一个块更改为BEGIN {a=2}
.
请注意,您的示例输入在第二个之后有一个空行x x x...
,如果我们停止删除该行中的行,它仍保留在输出中x x x...
。
答案3
grep -Pz '(?s)<!--START OF FILE(.*?x x x x x x x){2}\K.*' input.txt
解释
grep -Pz
-P
- 将模式解释为 Perl 兼容的正则表达式 (PCRE)。-z
- 将其input.txt
作为一条大线进行处理。
(?s)<!--START OF FILE(.*?x x x x x x x){2}\K.*
(?s)
- 为正则表达式的其余部分打开“点匹配换行符”。.*?
- 非贪婪匹配。{2}
- 模式的重复次数。\K
- 从最终匹配的字符串中省略任何先前匹配的字符。
答案4
这个片段:
# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
pl " Input data file $FILE:"
head -v -n 20 $FILE
pl " Expected output on file $E:"
head -v $E
pl " Results:"
cgrep -V -D -w '<!--START OF FILE -->' +2 +w 'x x x x x x x' 'meta' $FILE
产生:
-----
Input data file data1:
==> data1 <==
<!--START OF FILE -->
random text
<meta> more random text </meta>
x x x x x x x
more random text
that I dont need
x x x x x x x
I need everything
from this point
-----
Expected output on file expected-output1:
I need everything
from this point
onwards
...
-----
Results:
I need everything
from this point
onwards
...
这会省略 (-V) 一个以“...START...”开始 (-w) 并以第二次出现 (+2) 字符串“...x x...”结束 (+w) 的窗口。 ' 窗口内有字符串 'meta'。
在这样的系统上:
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution : Debian 8.9 (jessie)
bash GNU bash 4.3.30
cgrep 的一些详细信息:
cgrep shows context of matching patterns found in files (man)
Path : ~/executable/cgrep
Version : 8.15
Type : ELF 64-bit LSB executable, x86-64, version 1 (SYS ...)
Home : http://sourceforge.net/projects/cgrep/ (doc)
虽然需要获取并编译 cgrep,但我在 32 位或 64 位系统上做到这一点没有任何问题,并且它可以通过brew 在 macOS (High Sierra) 上使用。执行时间与 GNU grep 相当。
最美好的祝愿...干杯,drl