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

时间:2014-08-10 10:39:43

标签: bash text sed

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

我已经知道如何使用sed删除第3行到第10行,但我想知道是否有办法只使用一个命令行进行所有删除操作。我可以使用for loop,但问题是,每次循环迭代时,行号将被更改,并且需要对要删除的行号进行一些额外的计算。

5 个答案:

答案 0 :(得分:5)

这是一个awk oneliner,无论你的文件有40行还是40k行,都能满足你的需求:

awk 'NR~/[12]$/' file

例如,有50行:

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

答案 1 :(得分:2)

这可能适合你(GNU sed):

sed '3~10,+7d' file

删除范围为3的行,此后删除步骤10,以删除以下7行。

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

sed '41,$b;3~10,+7d' file

第一条指令告诉sed忽略第41行到文件结尾。

也可写:

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

答案 2 :(得分:1)

sed -i '3,10d;13,20d;23,30d;33,40d' file

答案 3 :(得分:0)

awk '{m=NR%10} !(m==0 || m>=3)' file > tmp && mv tmp file

答案 4 :(得分:0)

@ Kent的回答是这种特殊情况的方法,但总的来说:

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

即使你想从每13个中选择第4到第7行,上述内容也会有效,例如:

$ 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

它不受约于N的限制。

或者只选择每13个中的第3行,第5行和第6行:

$ 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

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