clw*_*wen 62 command-line files command
是否有任何 Linux 命令可以用来对文件的子集进行采样?例如,一个文件包含一百万行,我们只想从该文件中随机抽取一千行。
对于随机,我的意思是每条线都有相同的被选择概率,并且所选择的线都不是重复的。
head并且tail可以选择文件的子集但不能随机选择。我知道我总是可以编写一个 python 脚本来这样做,但只是想知道是否有这种用法的命令。
der*_*ert 97
该shuf命令(coreutils的部分)可以这样做:
shuf -n 1000 file
Run Code Online (Sandbox Code Playgroud)
至少对于现在的非古代版本(在2013年的提交中添加),它将在适当的时候使用水库采样,这意味着它不应该耗尽内存并使用快速算法。
Txa*_*gel 33
如果您有一个非常大的文件(这是取样的常见原因),您会发现:
shuf 耗尽记忆$RANDOM如果文件超过 32767 行,则使用将无法正常工作如果您不需要“恰好”n 个采样行,您可以采样这样的比率:
cat input.txt | awk 'BEGIN {srand()} !/^$/ { if (rand() <= .01) print $0}' > sample.txt
这使用恒定内存,对文件的 1% 进行采样(如果您知道文件的行数,则可以调整此因子以对接近有限数量的行进行采样),并且适用于任何大小的文件,但它不会返回精确的行数,只是一个统计比率。
注意:代码来自:https : //stackoverflow.com/questions/692312/randomly-pick-lines-from-a-file-without-slurping-it-with-unix
geo*_*ory 10
类似于@Txangel 的概率解决方案,但速度接近 100 倍。
perl -ne 'print if (rand() < .01)' huge_file.csv > sample.csv
Run Code Online (Sandbox Code Playgroud)
如果您需要高性能、精确的样本大小,并且乐于忍受文件末尾的样本间隙,您可以执行以下操作(从 1m 行文件中抽取 1000 行样本):
perl -ne 'print if (rand() < .0012)' huge_file.csv | head -1000 > sample.csv
Run Code Online (Sandbox Code Playgroud)
.. 或者确实链接第二个示例方法而不是head.
如果shuf -n大文件的技巧耗尽内存并且您仍然需要固定大小的示例并且可以安装外部实用程序,请尝试示例:
$ sample -N 1000 < FILE_WITH_MILLIONS_OF_LINES
Run Code Online (Sandbox Code Playgroud)
需要注意的是,样本(示例中为1000 行)必须适合内存。
免责声明:我是推荐软件的作者。