从文件中获取等间距的 n 行

Get n lines from file which are equal spaced

我有一个包含 1000 行的大文件 lines.I 想从中获取 110 行。 输入文件中的行应均匀分布。

例如,我从 10 行的文件中读取了 4 行

输入文件

1
2
3
4
5
6
7
8
9
10

输出文件:

1
4
7
10

使用:

sed -n '1~9p' < file

-n 选项将停止 sed 输出任何内容。 '1~9p' 告诉 sed 从第 1 行开始每 9 行打印一次(末尾的 p 命令 sed 打印)。

要接近 110 行,您必须每 9 行打印一次 (1000/110 ~ 9)。


更新: 这个答案将打印 112 行,如果你正好需要 110 行,你可以像这样使用 head 来限制输出:

sed -n '1~9p' < file | head -n 110

使用 awk 可以做到:

 awk -v interval=3 '(NR-1)%interval==0' file

其中间隔是打印的连续行之间的行数差异。该值实质上是文件中的总行数除以打印的行数。

$ cat tst.awk
NR==FNR { next }
FNR==1 { mod = int((NR-1)/tgt) }
!( (FNR-1)%mod ) { print; cnt++ }
cnt == tgt { exit }

$ wc -l file1
1000 file1

$ awk -v tgt=110 -f tst.awk file1 file1 > file2

$ wc -l file2
110 file2

$ head -5 file2
1
10
19
28
37

$ tail -5 file2
946
955
964
973
982

请注意,根据您发布的输入文件,这不会产生您在问题中发布的输出,因为这需要一种算法,该算法并不总是在输出行之间使用相同的间隔。如果愿意,您可以动态计算 mod 并在解析输入文件时对其进行调整,但上述内容可能就足够了。

我经常喜欢结合使用 shell 和 awk 来处理这些事情

#!/bin/bash

filename=
toprint=

awk -v tot=$(expr $(wc -l < $filename)) -v toprint=$toprint '
BEGIN{ interval=int((tot-1)/(toprint-1)) }

(NR-1)%interval==0 {
    print;
    nbr++
}

nbr==toprint{exit}

' $filename

一些例子:

$./spread.sh 1001lines 5
1
251
501
751
1001
$ ./spread.sh 1000lines 110 |head -n 3
1
10
19
$ ./spread.sh 1000lines 110 |tail -n 3
964
973
982