列出目录中的X个随机文件


Answers:


7

由于您提到的是zsh:

rand() REPLY=$RANDOM
print -rl -- *(o+rand[1,30])

您可以print用say ogg123*say 代替**/*.ogg


19

尝试将ls输出管道传输到shuf,例如

$ touch 1 2 3 4 5 6 7 8 9 0
$ ls | shuf -n 5
5
9
0 
8
1

-n标志指定您需要多少个随机文件。


command not found(未安装):/
Amelio Vazquez-Reina 2012年

奇怪...它应该是coreutils的一部分。如果您的coreutils很旧,那么该命令将不存在。
雷南2012年

6
这是一种快速而又肮脏的方法,我也将使用它—用于一次性脚本。对于更耐用的方法,请避免解析的输出ls
janmoesen 2012年

@janmoesen我对此一无所知。谢谢!
雷南2012年

@Renan并非每个Unix默认都安装了GNU coreutils。
库萨兰达

2

只需一点点Perl即可解决此问题。从当前目录中随机选择四个文件:

perl -MList::Util=shuffle -e 'print shuffle(`ls`)' | head -n 4

不过,对于生产用途,我将使用不依赖于ls输出,可以接受任何目录,检查您的args等的扩展脚本。请注意,随机选择本身仍然只有几行。

#!/usr/bin/perl    
use strict;
use warnings;
use List::Util qw( shuffle );

if ( @ARGV < 2 ) {
    die "$0 - List n random files from a directory\n"
        . "Usage: perl $0 n dir\n";
}
my $n_random = shift;
my $dir_name = shift;
opendir(my $dh, $dir_name) || die "Can't open directory $dir_name: $!";

# Read in the filenames in the directory, skipping '.' and '..'
my @filenames = grep { !/^[.]{1,2}$/ } readdir($dh);
closedir $dh;

# Handle over-specified input
if ( $n_random > $#filenames ) {
    print "WARNING: More values requested ($n_random) than available files ("
          . @filenames . ") - truncating list\n";
    $n_random = @filenames;
}

# Randomise, extract and print the chosen filenames
foreach my $selected ( (shuffle(@filenames))[0..$n_random-1] ) {
    print "$selected\n";
}

恕我直言,Perl脚本不是“标准的Unix命令”。在任何高级脚本语言(例如Perl,Python或Ruby)中,此问题都很容易解决,但如果直接在命令行上,则更有趣。
Gerrit 2012年

1
@gerrit-我明白你的意思。我提供此信息是因为,shuf对于OP ,首选答案(使用)不足。关于什么是标准Unix,什么不是标准Unix-Perl随处可见,它简洁而强大地解决了该问题。如果我将其作为Perl的一线工具,那该算作“命令行”吗?Perl强大的事实是否真的反对此答案的存在?
ire_and_curses 2012年

我会说这是对另一个问题的答案。当然,在任何功能齐全的编程语言中,这个问题都是微不足道的,对我来说,问题的有趣之处在于,是否可以/不/使用大约20个LOC脚本来完成此问题?脚本语言功能强大,但是我不认为Perl被归类为命令(例如OP所要求的;不,如果您给出了200个字符的命令行来调用Perl,我会有相同的看法)。
Gerrit 2012年

@gerrit-也许我可以更清楚。看一下我的编辑内容:perl -MList::Util=shuffle -e 'print shuffle(ls )' | head -n 4更像您想要的内容吗?
ire_and_curses 2012年

是的,我删除了我的选票,这肯定有点苛刻。
Gerrit 2012年

1

一个简单的解决方案,它避免了ls的解析,并且还可以使用空格:

shuf -en 30 dir/* | while read file; do
    echo $file
done

从其他注释中可以看出,OP在没有的系统上shuf
库沙兰丹

shuf问题中没有提到避免。这个答案对其他用户仍然有帮助。
scai

0

仅使用Zsh的oneliner:

files=(*); for x in {1..30}; do i=$((RANDOM % ${#files[@]} + 1)); echo "${files[i]}"; done

在Bash中相同,其中数组索引从零开始:

files=(*); for x in {1..30}; do i=$((RANDOM % ${#files[@]})); echo "${files[i]}"; done

请注意,两个版本都不考虑重复项。


1
这可能会多次列出同一文件。避免这是问题的重要部分。
吉尔(Gilles)“所以

Gilles:完全正确,这就是为什么我说“请注意,两个版本都没有考虑重复项。” 如果您不关心时间复杂度,并且每次从阵列中删除一个随机数组时都重建数组,则仍然可以在纯Bash中执行此操作。那时甚至还没有接近单线,但这当然不是必须的。
janmoesen 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.