在Unix命令行中从文件中读取随机行的简单方法是什么?

251 unix linux random command-line

在Unix命令行中从文件中读取随机行的简单方法是什么?

小智 366

你可以使用shuf:

shuf -n 1 $FILE
Run Code Online (Sandbox Code Playgroud)

还有一个叫做的工具rl.在Debian中,它在randomize-lines包中完全符合您的要求,但并非在所有发行版中都可用.在它的主页上,它实际上建议使用shuf替代(我相信它在创建时不存在). shuf是GNU coreutils的一部分,rl不是.

rl -c 1 $FILE
Run Code Online (Sandbox Code Playgroud)

  • 你可以通过从Homebrew安装`coreutils`来获得OS X上的shuf.可能被称为`gshuf`而不是`shuf`. (23认同)
  • 而且,如果处理相当大的文件 - 80kk行,那么`sort -R`绝对会让人等待很多**,而`shuf -n`会立即行动起来. (5认同)
  • 请注意,`shuf` 是 [GNU Coreutils](https://en.wikipedia.org/wiki/GNU_Core_Utilities) 的一部分,因此在 *BSD 系统(或 Mac?)上不一定可用(默认情况下)。@Tracker1 下面的 perl one-liner 更便携(根据我的测试,速度稍快)。 (4认同)
  • 感谢`shuf`提示,它内置在Fedora中. (2认同)
  • 同样,你可以通过`brew install randomize-lines在OS X上使用`randomize-lines`; rl -c 1 $ FILE` (2认同)

Pol*_*ker 73

另一种选择:

head -$((${RANDOM} % `wc -l < file` + 1)) file | tail -1
Run Code Online (Sandbox Code Playgroud)

  • $ {RANDOM}仅生成小于32768的数字,因此不要将其用于大文件(例如英语词典). (28认同)
  • 您可以使用`($ {RANDOM} << 15)+ $ {RANDOM}`将其扩展为30位随机数.这大大减少了偏差,并允许它适用于包含多达10亿行的文件. (10认同)
  • 由于模运算,这并不能为每条线提供精确相同的概率.如果文件长度为<< 32768(如果它除了那个数字则完全没有),这几乎不重要,但可能值得注意. (3认同)

Tho*_*ele 65

sort --random-sort $FILE | head -n 1
Run Code Online (Sandbox Code Playgroud)

(我喜欢上面的shuf方法甚至更好 - 我甚至不知道存在,我自己也没有找到这个工具)

  • +1我喜欢它,但你可能需要一个非常新的`sort`,不适用于我的任何系统(CentOS 5.5,Mac OS 10.7.2).此外,无用的cat,可以简化为`sort --random-sort <$ FILE | 头-n 1` (10认同)
  • 这是相对较慢的,因为整个文件需要在将它排到"head"之前通过`sort`进行洗牌.`shuf`选择文件中的随机行,而对我来说要快得多. (5认同)
  • `--random-sort`和`-R`选项特定于GNU排序(因此它们不适用于BSD或Mac OS`sort`).GNU排序在2005年学习了那些标志,因此你需要GNU coreutils 6.0或更新版本(例如CentOS 6). (5认同)

Yok*_*kai 31

这很简单.

cat file.txt | shuf -n 1
Run Code Online (Sandbox Code Playgroud)

当然,这比它自己的"shuf -n 1 file.txt"要慢一点.

  • 最佳答案。我不知道这个命令。请注意,-n 1指定1行,您可以将其更改为1行以上。Shuf也可以用于其他用途。我只是用管道输送了“ ps aux”和“ grep”,以随机杀死部分匹配名称的进程。 (2认同)

Tra*_*er1 16

perlfaq5:如何从文件中选择随机行?以下是Camel Book中的油藏采样算法:

perl -e 'srand; rand($.) < 1 && ($line = $_) while <>; print $line;' file
Run Code Online (Sandbox Code Playgroud)

这在读取整个文件的空间方面具有显着的优势.您可以在Donald E. Knuth的"计算机编程艺术"第2卷第3.4.2节中找到这种方法的证明.

  • 这是猫的无用用途.这是对perlfaq5中的代码的略微修改(以及骆驼书的礼貌):perl -e's srand; rand($.)<1 &&($ line = $ _)而<>; 打印$ line;' 文件名 (3认同)
  • 更值得深思:[`shuf`将整个输入文件存储在内存中](/sf/ask/647194691/#comment40771587_9245733) ,这是一个可怕的想法,而这段代码只存储一行,所以这段代码的限制是INT_MAX的行数(2 ^ 31或2 ^ 63,具体取决于你的拱门),假设任何选定的潜在行适合记忆. (2认同)

Pao*_*sco 11

使用bash脚本:

#!/bin/bash
# replace with file to read
FILE=tmp.txt
# count number of lines
NUM=$(wc - l < ${FILE})
# generate random number in range 0-NUM
let X=${RANDOM} % ${NUM} + 1
# extract X-th line
sed -n ${X}p ${FILE}
Run Code Online (Sandbox Code Playgroud)