美好的一天,我想知道如何删除这样的文本块:
1
2
3
4
5
6
7
8
并从第二行删除直到最后一行之前的第三行,以获得:
1
2
6
7
8
提前致谢!!!
顺便说一句,这个文本块只是一个例子,我处理的真实文本块很大,而且每个文本块的行号都不同。
这可能对您有用(GNU sed):
sed '3,${:a;$!{N;s/\n/&/3;Ta;D}}' file
或者,如果您愿意:
sed '1,2b;:a;$!{N;s/\n/&/3;Ta;D}' file
这些总是打印前两行,然后构建一个三行的运行窗口。除非到达文件末尾,否则第一行会从窗口中弹出并删除。在文件末尾打印剩余的 3 行。
获取用于打印请求范围的行wc
数awk
:
$ awk 'NR<M || NR>N-M' M=3 N="$(wc -l file)" file
1
2
6
7
8
这使您只需更改 的值即可轻松更改范围M
。
因为你提到了巨大的,而且行号也可能不同。我会建议这个 awk 单线:
awk 'NR<3{print;next}{delete a[NR-3];a[NR]=$0}END{for(x=NR-2;x<=NR;x++)print a[x]}' file
x
到$-y
,您只需更改 oneliner 中的偏移量。添加测试:
kent$ seq 8|awk 'NR<3{print;next}{delete a[NR-3];a[NR]=$0}END{for(x=NR-2;x<=NR;x++)print a[x]}'
1
2
6
7
8
使用sed:
sed -n '
## Append second line, print first two lines and delete them.
N;
p;
s/^.*$//;
## Read next three lines removing leading newline character inserted
## by the "N" command.
N;
s/^\n//;
N;
:a;
N;
## I will keep three lines in buffer until last line when I will print
## them and exit.
$ { p; q };
## Not last line yet, so remove one line of buffer based in FIFO algorithm.
s/^[^\n]*\n//;
## Goto label "a".
ba
' infile
它产生:
1
2
6
7
8