打印n行,然后在大型文本文件中跳过n行。

3

我想使用sed命令在文本文件中从特定行开始,按照一定规律打印n行,跳过n行,再打印n行等等,直到文件结尾。例如,从第4行开始,打印第5-9行,跳过10-14行,再打印第15-19行等等。
以下是需要翻译的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

I want

5
6
7
8
9
15
16
17
18
19
25
26
27
28
29
35
36
37
38
39
etc

如果我尝试

sed -n '4~5p' FILE.txt > NEWFILE.txt 

将给我

4

9

14

19

这不是我想要的。


2
这似乎更适合使用 awk - Barmar
你有没有读标签描述?n是用于管理多个Node.js/io.js版本的CLI。这与sed有什么关系? - Barmar
当我尝试您的命令时,我得到的是4、9、14、20,而不是您展示的相同行。 - Barmar
如果您的问题已经解决,请标记其中一个答案为已接受,以便该问题不再显示为未解决。谢谢。 - tripleee
谢谢,Ed Morton。问题已经解决了。对不起,大家。这是我第一次尝试询问stackoverflow的神谕,并且似乎有些粗心。抱歉浪费大家的时间。 - Stanza Alley
显示剩余4条评论
4个回答

3

我认为在 sed 中没有简单的方法可以做到这一点,因为它不能进行算术运算。更好的选择是使用 awk

awk 'NR%10 >= 5' FILE.txt > NEWFILE.txt

NR%10 表示记录号除以 10 的余数(即行号的最后一位数字)。因此,这将打印出任何行号的最后一个数字至少为 5 的行:5-9、15-19、25-29,依此类推。


谢谢Barmar。这将跳过10-14,以便它按照承诺工作,但我也试图跳过20-24、30-34等... - Stanza Alley
这就是它的作用。NR%10是行号的最后一位数字。因此,它只打印行号最后一位为5或更高的行。 - Barmar

2

sed 仅用于对单个行进行简单的替换,只需使用 awk:

$ awk '!(NR%5){f=!f} f' file
5
6
7
8
9
15
16
17
18
19

不是绝对正确的,但同意Awk是这个特定任务和许多其他任务更自然的工具。 - tripleee
我已经使用sed超过30年,几乎每天都在使用它。我知道很难相信,但当你实际尝试提出其他应用程序时,在sed解决方案比等效的awk解决方案更好的情况下,我认为这些情况不存在,因为如果/当有小的需求变化时,sed解决方案始终更难理解和修改,并且sed解决方案会根据稍微不同的要求构造而大幅改变。请参见http://awk.info/?doc/tip/sedInAwk.html以获取一些sed / awk等效代码的示例。 - Ed Morton
sed可以在匹配中使用反向引用,从而使其能够匹配一些非正则上下文无关语言的子集,而awk不能轻松处理。如果您需要这个功能,通常awk不是一个选项,而sed可能是(尽管此时您可能要考虑使用perl)。我同意大多数情况下,复杂的sed(即超出一系列s///语句的任何内容)更适合用于有趣的谜题而不是生产。 - Wintermute
我理解并且确信使用它们可能会对简洁性产生一些影响,但在30多年的UNIX脚本编写中,我从未在LHS上使用过反向引用,也不记得曾经希望使用它,因此在我处理必须使用它们的情况时,sed或awk中总是有一个简单的替代方法(perl在我工作的许多机器上都不可用)。我想你的情况可能不同,但我无法想象LHS反向引用的好处是否值得处理复杂的sed脚本的其余部分。 - Ed Morton
然后你输入了脚本而不是复制/粘贴它,并在此过程中犯了一个错误。哦等一下,也许你的shell将!附加到某些特定含义 - 如果是这样,请阅读您的shell手册(和/或参见http://unix.stackexchange.com/a/3748/133219)并禁用该功能或将脚本存储在文件中并以这种方式执行。 - Ed Morton

2
这可能适用于您(GNU sed):
sed -n '5~10,+4p' file

使用一个区间,其中第一个地址从第5行开始每10行一步,第二个地址是第一个地址后4行。 详情请参见此处
另外,sed -n '4~5p' 并不能得到您想要的答案。

谢谢Potong。这将跳过10-14,但我也试图跳过20-24、30-34等...<br/>我已经为我的sed输出添加了错误的文本-'4~5p',现在已经修复。 - Stanza Alley
@StanzaAlley 这个解决方案可以实现这个功能。 - potong

2
这里有一个sed解决方案。试着弄清楚吧 ;)
sed -n 'n ; n ; n ; n ; n ; h ; n ; H ; n ; H ; n ; H ; n ; H ; x ; p' file

谢谢henrikgiesel。这个例子确实完美地解决了我的问题,但我担心如果我想跳过500行文本,它可能会变得有些笨重,所以我会继续寻找... - Stanza Alley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接