【发布时间】:2014-02-14 01:13:30
【问题描述】:
我需要删除文本文件中的奇数行以进行下采样。我找到了这个命令,
awk 'NR%2==0' file
但它只打印终端中的奇数行。如何真正删除它们?
我并不关心偶数或奇数,我希望将它们从文件中删除或打印到另一个文件中。这只会在终端中打印它们。
【问题讨论】:
-
你确定
awk 'NR%2==0' file打印奇数行吗?
我需要删除文本文件中的奇数行以进行下采样。我找到了这个命令,
awk 'NR%2==0' file
但它只打印终端中的奇数行。如何真正删除它们?
我并不关心偶数或奇数,我希望将它们从文件中删除或打印到另一个文件中。这只会在终端中打印它们。
【问题讨论】:
awk 'NR%2==0' file 打印奇数行吗?
% 是一个取模运算符,NR 是当前行号,所以NR%2==0 仅适用于偶数行,并且会为它们调用默认规则 ({ print $0 })。因此只保存偶数行,将输出从awk重定向到一个新文件:
awk 'NR%2==0' infile > outfile
您可以使用sed 完成同样的事情。 devnulls 答案显示了如何使用 GNU sed 进行操作。
以下是没有~ 运算符的sed 版本的替代方案:
保持奇数行
sed 'n; d' infile > outfile
保持线条均匀
sed '1d; n; d' infile > outfile
【讨论】:
awk 'NR%2!=0' infile > outfile 保存 odd 行;使用awk,您不能替换输入文件,使用sed,您可以:使用选项-i ''(在Linux 上,-i 也可以)。
使用 GNU sed:
sed -i '0~2d' filename
从文件中删除偶数行。
用于删除奇数行:
sed -i '1~2d' filename
-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'.
【讨论】:
man sed 的旅行:地址m~n 表示:“从第m 行开始并匹配之后的第n 行”(而d 表示“删除”)。
这可能对您有用(GNU 和非 GNU sed):
sed -n 'p;n' file # keep odd
sed -n 'n;p' file # keep even
-n: 禁止打印
p: 打印当前行
n: 下一行
【讨论】:
-n 表示禁止打印。 p 表示打印这一行。 n 表示下一行。
~ 运算符的非 gnu sed(例如 mac)。
不要专注于负面(删除线条),专注于正面(选择线条),您的解决方案也会效仿。因此,您应该考虑I need to select even lines 而不是I need to remove odd lines,然后解决方案很简单:
awk '!(NR%2)' file
如果要将结果保存到新文件:
awk '!(NR%2)' file > newfile
或回到原来的:
awk '!(NR%2)' file > newfile && mv newfile file
【讨论】:
这是一个 awk 示例,用于创建两个分别包含奇数行和偶数行的新文件:
awk '{ if (NR%2) print > "odd.txt"; else print > "even.txt" }' input.txt
【讨论】:
>,而不是>>(记住这是awk,不是shell)。另外,您可以将整个内容缩写为{ print > ((NR%2?"odd":"even") ".txt") }
将偶数打印到新文件的 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
【讨论】: