从文件中获取等间距的 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
我有一个包含 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