【问题标题】:print n lines, then skip n lines in large text file打印 n 行,然后在大文本文件中跳过 n 行
【发布时间】:2016-05-21 17:25:24
【问题描述】:

我想使用 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

我想要

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

我不想要的。

【问题讨论】:

  • 这似乎更适合awk
  • 您是否费心阅读标签说明? n 是一个用于管理多个 Node.js / io.js 版本的 CLI。 这与 sed 有什么关系?
  • 当我尝试你的命令时,我得到4, 9, 14, 20,与你显示的不同。
  • 您的意思是在您的示例输入中跳过18 吗?如果是,请解释原因,如果不是,请修复它。
  • 如果您的问题现在已经解决,请将其中一个答案标记为已接受,这样这个问题就不会再出现未解决的问题。谢谢。

标签: bash sed


【解决方案1】:

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

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

NR%10 是记录号模 10(即行号的最后一位)。因此,这将打印行号的最后一位至少为 5 的任何行:5-9、15-19、25-29 等。

【讨论】:

  • 谢谢巴马尔。这将跳过 10-14,因此它按承诺工作,但我也在尝试跳过 20-24、30-34 等...
  • 这就是它的作用。 NR % 10 是行号的最后一位。所以它只打印最后一位为 5 或更高的行。
【解决方案2】:

sed 用于在单独的行上进行简单的替换,仅此而已。只需使用 awk:

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

【讨论】:

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

这是一个 sed 解决方案。试着弄清楚;)

sed -n 'n ; n ; n ; n ; n ; h ; n ; H ; n ; H ; n ; H ; n ; H ; x ; p' file

【讨论】:

  • 感谢 henrikgiesel。这实际上非常适合这个例子,但我担心如果我想跳过 500 行文本,它可能会变得有点笨拙,所以我会继续寻找......跨度>
【解决方案4】:

这可能对你有用(GNU sed):

sed -n '5~10,+4p' file

使用第一个地址从第 5 行开始步进 10 行,第二个地址在第一个地址之后 4 行的范围。 详情请见here

顺便说一句,sed -n '4~5p' 并没有给出你想的答案。

【讨论】:

  • 谢谢波东。这将跳过 10-14,但我也在尝试跳过 20-24、30-34 等...
    我为 sed -n '4~5p' 的输出添加了错误的文本 -现已修复
  • @StanzaAlley 这个解决方案可以做到这一点。
猜你喜欢
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-13
  • 2013-08-23
  • 2017-01-21
相关资源
最近更新 更多