从文本文件中删除奇数或偶数行

49

我需要从文本文件中删除奇数行以进行降采样。我找到了这个命令,

awk 'NR%2==0' file

但它只在终端打印奇数行。如何真正删除它们?

我不在乎行数是奇数还是偶数,我想把它们从文件中删除或将它们打印到另一个文件中。这只会在终端上打印它们。


你确定 awk 'NR%2==0' file 打印 奇数行吗? - devnull
6个回答

88

awk

% 是求模运算符,NR 表示当前行号,所以 NR%2==0 只对偶数行为真,并且将调用它们的默认规则 ({ print $0 })。因此,为了仅保留偶数行,请将输出从 awk 重定向到一个新文件中:

awk 'NR%2==0' infile > outfile

sed

你可以使用 sed 完成同样的事情。 devnulls 的答案展示了如何在 GNU sed 中实现。 以下是不具备 ~ 操作符的 sed 版本的替代方法:

保留奇数行

sed 'n; d' infile > outfile

保持偶数行

sed '1d; n; d' infile > outfile

好的,我并不在意奇偶数,我想把它们从文件中删除或打印到另一个文件中。这只会在终端上打印它们。 - SamuelNLP
3
好东西;完善一下:awk 'NR%2!=0' infile > outfile 保存了奇数行,使用 awk 时无法就地替换输入文件,但是可以使用 sed 替换:使用选项 -i ''(在Linux上,只需 -i 即可)。 - mklement0

18

使用GNU sed:

sed -i '0~2d' filename

从文件中删除偶数行。

要删除奇数行:

sed -i '1~2d' filename
< p > -i 选项会使更改直接保存到文件中。

引用手册的说法:

`FIRST~STEP'
     This GNU extension matches every STEPth line starting with line
     FIRST.  In particular, lines will be selected when there exists a
     non-negative N such that the current line-number equals FIRST + (N
     * STEP).  Thus, to select the odd-numbered lines, one would use
     `1~2'; to pick every third line starting with the second, `2~3'
     would be used; to pick every fifth line starting with the tenth,
     use `10~5'; and `50~0' is just an obscure way of saying `50'.

7
很好;为了潜在地节省其他人去“man sed”的旅程:地址“m~n”意味着:“从第m行开始,每隔n行匹配一次”(而“d”表示“删除”)。 - mklement0

12

这可能适用于你(无论是GNU还是非GNU的sed):

 sed -n 'p;n' file # keep odd
 sed -n 'n;p' file # keep even

-n:抑制打印输出

p:打印当前行

n:下一行


3
-n 表示禁止打印。p 表示打印此行。n 表示下一行。 - wisbucky
这个答案非常好,因为它适用于不支持~运算符的非GNU sed(例如mac)。 - wisbucky

5

不要关注负面(删除行),而是关注正面(选择行),你的解决方案就会跟着来。所以,与其想“我需要删除奇数行”,你应该考虑“我需要选择偶数行”,然后解决方案就很简单:

awk '!(NR%2)' file

如果您想将结果保存在新文件中:
awk '!(NR%2)' file > newfile

或者返回原始状态:

awk '!(NR%2)' file > newfile && mv newfile file

3
这是一个使用 awk 的示例,可以创建两个新文件,分别包含奇数行和偶数行:
awk '{ if (NR%2) print > "odd.txt"; else print > "even.txt" }' input.txt

1
请使用>而不是>>(请记住这是awk,而不是shell)。此外,您可以将整个内容缩写为{ print > ((NR%2?"odd":"even") ".txt") } - Ed Morton
有道理,尽管如果这两个文件之前都不存在,它们是相当等价的。而且对我来说,缩写的代码可读性稍差一些,所以,虽然我可能会在维护脚本时这样做,但我并不总是建议其他人使用这种程度的简洁性... - twalberg

1

输出偶数到新文件的Perl解决方案:

perl -lne 'print if $. % 2 == 0' infile > outfile

为了打印出奇数,请将== 1 更改为 == 0

$. 是行号

仅保留原始文件中的偶数:

perl -i -lne 'print if $. % 2 == 0' infile

与上面相同,但会创建名为infile.bak的备份文件:

perl -i.bak -lne 'print if $. % 2 == 0' infile

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