假设一个包含40行数据的文本文件。如何使用bash脚本删除3到10行,13到20行,23到30行,33到40行?
我已经知道如何使用sed
删除第3行到第10行,但我想知道是否有办法只使用一个命令行进行所有删除操作。我可以使用for loop
,但问题是,每次循环迭代时,行号将被更改,并且需要对要删除的行号进行一些额外的计算。
答案 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。