Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在bash中删除文本文件的多行块_Bash_Text_Sed - Fatal编程技术网

在bash中删除文本文件的多行块

在bash中删除文本文件的多行块,bash,text,sed,Bash,Text,Sed,假设一个包含40行数据的文本文件。如何使用bash脚本就地删除第3到10行、第13到20行、第23到30行、第33到40行 我已经知道如何使用sed删除第3行到第10行,但是我想知道是否有一种方法可以用一个命令行完成所有的删除操作。我可以使用for loop,但问题是,每次循环都会更改行号,并且需要删除一些额外的行号计算。这里有一个awk oneliner,适用于您的需要,无论您的文件有40行还是40k行: sed -i '3,10d;13,20d;23,30d;33,40d' file aw

假设一个包含40行数据的文本文件。如何使用bash脚本就地删除第3到10行、第13到20行、第23到30行、第33到40行


我已经知道如何使用sed删除第3行到第10行,但是我想知道是否有一种方法可以用一个命令行完成所有的删除操作。我可以使用for loop,但问题是,每次循环都会更改行号,并且需要删除一些额外的行号计算。

这里有一个awk oneliner,适用于您的需要,无论您的文件有40行还是40k行:

sed -i '3,10d;13,20d;23,30d;33,40d' file
awk 'NR~/[12]$/' file
例如,对于50行:

kent$ seq 50|awk 'NR~/[12]$/'  
1
2
11
12
21
22
31
32
41
42

这可能适用于GNU sed:

sed '3~10,+7d' file
删除范围为3的行,然后删除以下7行的步骤10

如果文件长度超过40行,而您只对前40行感兴趣:

sed '41,$b;3~10,+7d' file
第一条指令告诉sed忽略文件末尾的第41行

也可以写成:

sed '1,40{3~10,+7d}' file

@肯特的答案是针对这一特殊情况的解决办法,但总的来说:

$ seq 50 | awk '{idx=(NR%10)} idx>=1 && idx<=2'
1
2
11
12
21
22
31
32
41

关键是-选择行的范围是awk的工作,绝对不是sed。

@Cyrus的答案是解决这种情况的方法,但为了将来参考,您还可以添加多个命令来执行单个sed调用。。。sed-e'3,10d'-e'14d'-e'22s/a/b/'@Kent的答案肯定是正确的。它简单、健壮、可扩展,等等。不要说你想删除这个和这个,你可以说我想保留所有像这样的行1,2 11,12 21,22或类似的行,行号以1或2结尾的所有行应保持+1。我本来打算使用NR%10,但实际上我更喜欢这种方式。@TomFenech NR%10需要像NR%10&&NR%10或NR%10~/[12]这样的后处理/但是,当您可以像刚才那样匹配最后一个数字时,就没有必要了。@Kent您可以解释一下您实际上在做什么——即执行awk的默认操作,即如果行号以数字1或2结尾,则打印当前行。而且,它并不像OP要求的那样严格到位。不过你仍然可以得到我的+1:-@MarkSetchell-thanx投票,thanx解释。gawk 4.1.0有一个适当的选项。否则,awk'…'file>foo&&mv foo file您不需要存储整个文件。读取文件时执行筛选:awk'{m=NR%10}!m==0 | | m>3'是的,不知道我为什么这样写。我还误读了OP希望删除行,而不是打印。更新后,谢谢。这可以动态构建,如果这很重要的话:对于i=0;如果这个小范围内也可能出现以下情况:sed-i'N;PNNNNNNNNd'文件
$ seq 50 | awk '{idx=(NR%10)} idx>=1 && idx<=2'
1
2
11
12
21
22
31
32
41
$ seq 50 | awk '{idx=(NR%13)} idx>=4 && idx<=7'
4
5
6
7
17
18
19
20
30
31
32
33
43
44
45
46
$ seq 50 | awk 'BEGIN{split("3 5 6",tmp); for (i in tmp) tgt[tmp[i]]=1} tgt[NR%13]'
3
5
6
16
18
19
29
31
32
42
44
45