我想随机洗牌文本文件的行,并创建一个新文件。该文件可能有几千行。

我如何用cat, awk, cut等做到这一点?


当前回答

如果你安装了Scala,这里有一行代码来洗牌输入:

ls -1 | scala -e 'for (l <- util.Random.shuffle(io.Source.stdin.getLines.toList)) println(l)'

其他回答

我使用了一个小perl脚本,我称之为“unsort”:

#!/usr/bin/perl
use List::Util 'shuffle';
@list = <STDIN>;
print shuffle(@list);

我也有一个null分隔的版本,称为“unsort0”…方便使用find -print0等。

PS:我也投票给了“shuf”,我不知道现在coreutils有这个词……如果您的系统没有'shuf',上述方法可能仍然有用。

基于scai的答案的Python一行,但是a)接受stdin, b)使结果与seed可重复,c)只选出所有行的200行。

$ cat file | python -c "import random, sys; 
  random.seed(100); print ''.join(random.sample(sys.stdin.readlines(), 200))," \
  > 200lines.txt

一种简单而直观的方法是使用shuf。

例子:

假设words.txt为:

the
an
linux
ubuntu
life
good
breeze

要洗牌,请执行以下操作:

$ shuf words.txt

这将把打乱的行扔到标准输出;所以,你必须将它管道到一个输出文件,就像:

$ shuf words.txt > shuffled_words.txt

一次这样的洗牌可能会产生:

breeze
the
linux
an
ubuntu
good
life

这是第一次尝试,对编码器来说很容易,但对CPU来说很难,它在每行前加上一个随机数,对它们进行排序,然后从每行中剥离随机数。实际上,这些行是随机排序的:

cat myfile | awk 'BEGIN{srand();}{print rand()"\t"$0}' | sort -k1 -n | cut -f2- > myfile.shuffled

python的一行代码:

python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFile

如果只打印单个随机行:

python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFile

但是请参阅这篇文章了解python的random.shuffle()的缺点。它不能很好地处理很多(超过2080个)元素。