Rug*_*man 275 random shell awk command-line shuffle
我想随机地随机播放文本文件的行并创建一个新文件.该文件可能有几千行.
我怎样才能做到这一点与cat,awk,cut等?
Joe*_*oey 349
你可以用shuf.至少在某些系统上(似乎不在POSIX中).
正如jleedev所指出的那样:sort -R也许是一种选择.至少在一些系统上; 好吧,你得到了照片.有人指出,sort -R它并不是真正的混乱,而是根据它们的哈希值对项目进行排序.
[编者注:sort -R 几乎是随机播放,除了重复的行/排序键总是彼此相邻.换句话说:只有使用独特的输入行/键才是真正的随机播放.虽然输出顺序确实是由哈希值决定的,但随机性来自于选择随机哈希函数 - 参见手册.
小智 83
Perl one-liner将是Maxim解决方案的简单版本
perl -MList::Util=shuffle -e 'print shuffle(<STDIN>);' < myfile
Run Code Online (Sandbox Code Playgroud)
        mkl*_*nt0 60
这个答案通过以下方式补充了许多现有的答案:
现有答案打包成灵活的shell函数:
stdin输入,还包括文件名参数SIGPIPE通常的方式处理(使用退出代码安静终止141),而不是吵闹.将功能输出管道连接到提前关闭的管道(例如管道连接时)时,这一点很重要head.进行性能比较.
awk,sort以及cut改编自OP自己的答案:shuf() { awk 'BEGIN {srand(); OFMT="%.17f"} {print rand(), $0}' "$@" |
               sort -k1,1n | cut -d ' ' -f2-; }
Run Code Online (Sandbox Code Playgroud)
shuf() { perl -MList::Util=shuffle -e 'print shuffle(<>);' "$@"; }
Run Code Online (Sandbox Code Playgroud)
shuf() { python -c '
import sys, random, fileinput; from signal import signal, SIGPIPE, SIG_DFL;    
signal(SIGPIPE, SIG_DFL); lines=[line for line in fileinput.input()];   
random.shuffle(lines); sys.stdout.write("".join(lines))
' "$@"; }
Run Code Online (Sandbox Code Playgroud)
shuf() { ruby -e 'Signal.trap("SIGPIPE", "SYSTEM_DEFAULT");
                     puts ARGF.readlines.shuffle' "$@"; }
Run Code Online (Sandbox Code Playgroud)
表现比较:
注意:这些数字是在2012年末推出的带有3.2 GHz Intel Core i5的iMac和运行OSX 10.10.3的Fusion Drive上获得的.虽然时序会随着操作系统的使用而变化,机器规格,awk使用的实现(例如,awkOSX上使用的BSD 版本通常比GNU慢awk,尤其是mawk),这应该提供相对性能的一般意义.
输入文件是一个1百万行文件与产生seq -f 'line %.0f' 1000000.
时间按升序列出(最快速率):
shuf
0.090s0.289s0.589s1.342s用Python 2.7.6; 2.407s(!)使用Python 3.4.2awk+ sort+cut
3.003s与BSD awk; 2.388s与GNU awk(4.1.1); 1.811s与mawk(1.3.4);为进一步比较,未按上述功能打包的解决方案:
sort -R (如果有重复的输入行,则不是真正的随机播放)
10.661s - 分配更多内存似乎没有什么区别24.229sbash 循环+ sort
32.593s结论:
shuf如果可以的话,使用 - 它是迄今为止最快的.awk+ sort+ cut组合作为最后的手段 ; awk您使用哪种实现很重要(mawk比GNU快awk,BSD awk最慢).sort -R,bash循环和Scala.Nic*_*oic 27
我使用一个小的perl脚本,我称之为"unsort":
#!/usr/bin/perl
use List::Util 'shuffle';
@list = <STDIN>;
print shuffle(@list);
Run Code Online (Sandbox Code Playgroud)
我还有一个NULL分隔的版本,称为"unsort0"...用于查找-print0等等.
PS:也投了'shuf',我不知道这些天在coreutils中有什么......如果你的系统没有'shuf',上面的内容可能仍然有用.
Rug*_*man 20
这是第一次尝试在编码器上很容易但在CPU上很难为每行添加一个随机数,对它们进行排序然后从每一行中删除随机数.实际上,这些行是随机排序的:
cat myfile | awk 'BEGIN{srand();}{print rand()"\t"$0}' | sort -k1 -n | cut -f2- > myfile.shuffled
Run Code Online (Sandbox Code Playgroud)
        gho*_*g74 16
这是一个awk脚本
awk 'BEGIN{srand() }
{ lines[++d]=$0 }
END{
    while (1){
    if (e==d) {break}
        RANDOM = int(1 + rand() * d)
        if ( RANDOM in lines  ){
            print lines[RANDOM]
            delete lines[RANDOM]
            ++e
        }
    }
}' file
Run Code Online (Sandbox Code Playgroud)
产量
$ cat file
1
2
3
4
5
6
7
8
9
10
$ ./shell.sh
7
5
10
9
6
8
2
1
3
4
Run Code Online (Sandbox Code Playgroud)
        sca*_*cai 11
python的单线程:
python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFile
Run Code Online (Sandbox Code Playgroud)
并且只打印一条随机线:
python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFile
Run Code Online (Sandbox Code Playgroud)
但是请看这篇文章,了解python的缺点random.shuffle().它不适用于许多(超过2080个)元素.
简单的基于awk的功能将完成这项工作:
shuffle() { 
    awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, $0;}' | sort -n | cut -c8-
}
Run Code Online (Sandbox Code Playgroud)
用法:
any_command | shuffle
Run Code Online (Sandbox Code Playgroud)
这几乎适用于任何UNIX.在Linux,Solaris和HP-UX上测试过.
更新:
请注意,前导零(%06d)和rand()乘法使其在sort不理解数字的系统上也能正常工作.它可以通过词典顺序排序(也就是正常的字符串比较).
根据scai的答案,Python的一个衬里,但a)采用stdin,b)使结果可重复使用种子,c)只挑选出所有行中的200个.
$ cat file | python -c "import random, sys; 
  random.seed(100); print ''.join(random.sample(sys.stdin.readlines(), 200))," \
  > 200lines.txt
Run Code Online (Sandbox Code Playgroud)
        一种简单直观的方法是使用shuf。
例:
假设words.txt为:
the
an
linux
ubuntu
life
good
breeze
Run Code Online (Sandbox Code Playgroud)
要随机排列,请执行以下操作:
$ shuf words.txt
Run Code Online (Sandbox Code Playgroud)
这将乱码的线投向标准输出 ; 因此,您必须将其通过管道传输到类似以下的输出文件:
$ shuf words.txt > shuffled_words.txt
Run Code Online (Sandbox Code Playgroud)
一种这样的随机运行可以产生:
breeze
the
linux
an
ubuntu
good
life
Run Code Online (Sandbox Code Playgroud)
        我们有一个包来完成这项工作:
sudo apt-get install randomize-lines
Run Code Online (Sandbox Code Playgroud)
例子:
创建一个有序的数字列表,并将其保存到 1000.txt:
seq 1000 > 1000.txt
Run Code Online (Sandbox Code Playgroud)
洗牌,只需使用
rl 1000.txt
Run Code Online (Sandbox Code Playgroud)