Есть ли способ составить список, скажем, 30 случайных файлов из каталога, используя стандартные команды Linux? (в zsh
)
Верхний ответ, описанный здесь , не работает для меня ( sort
не распознает опцию -R
)
Есть ли способ составить список, скажем, 30 случайных файлов из каталога, используя стандартные команды Linux? (в zsh
)
Верхний ответ, описанный здесь , не работает для меня ( sort
не распознает опцию -R
)
Ответы:
Поскольку вы упоминаете Zsh:
rand() REPLY=$RANDOM
print -rl -- *(o+rand[1,30])
Вы можете заменить, print
скажем, ogg123
и *
сказать**/*.ogg
Попробуйте передать 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
(не установлено): /
ls
.
Это довольно легко решить с помощью чуть-чуть Perl. Выберите четыре файла случайным образом из текущего каталога:
perl -MList::Util=shuffle -e 'print shuffle(`ls`)' | head -n 4
Однако для производственного использования я бы пошел с расширенным сценарием, который не полагается на ls
вывод, может принять любой dir, проверить ваши аргументы и т. Д. Обратите внимание, что сам случайный выбор по-прежнему состоит всего из нескольких строк.
#!/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";
}
shuf
) не был достаточен для OP. Что касается и не является стандартным Unix - Perl существует повсюду, и он решает проблему кратко и надежно. Если бы я дал это как однострочник Perl, это бы считалось «командной строкой»? Является ли тот факт, что Perl является мощным аргументом против существования этого ответа?
perl -MList::Util=shuffle -e 'print shuffle(
Ls )' | head -n 4
Это больше похоже на то , что вы искали?
Простое решение, которое позволяет избежать анализа ls, а также работает с пробелами:
shuf -en 30 dir/* | while read file; do
echo $file
done
shuf
.
shuf
не упоминается в вопросе. Этот ответ по-прежнему будет полезен для других пользователей.
Онлайнер, использующий только Zsh:
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
Обратите внимание, что ни одна из версий не учитывает дубликаты.