如何更改for track in *.mp3; do
以便.mp3
以随机方式遍历当前目录中的所有文件?
答案1
作为参考,在 中zsh
,您可以使用 globbing 限定符影响 glob 扩展的顺序o
。例如*.mp3(om)
按修改时间排序。您可以使用函数定义自己的排序顺序。
使用 时*.mp3(o+foo)
,文件的排序不是基于文件名,而是基于函数在给定文件名的变量foo
中返回的值$REPLY
(也foo
接收文件名$REPLY
)。例如:
rand() REPLY=$RANDOM
for i in *.mp3(o+rand); do
echo "$i"
done
您会得到一个随机订单。
POSIXly,如果您不想对文件名可能包含的内容做出任何假设,您可以执行以下操作:
shuffle() {
awk -v q="'" 'BEGIN {
printf "set --"
for (i=1; i < ARGC; i++) {
r=int(rand()*(ARGC-1)+1);x=ARGV[i];ARGV[i]=ARGV[r];ARGV[r]=x
}
for (i=1;i<ARGC;i++) {
a=ARGV[i];gsub(q, q "\\" q q, a);printf " %s", q a q
}
print "";exit}' "$@"
}
eval "$(shuffle *.mp3)"
for i do
echo "$i"
done
答案2
您可以使用该shuf
命令为您打乱行顺序。只需反引号包含 *.mp3 的列表命令并将其通过管道传输到shuf
,例如:
#!/bin/bash -
SAVEIFS=$IFS
IFS=$'\n'; set -f
for i in `find . -maxdepth 1 -iname '*.mp3' -type f | shuf`
do
echo "$i"
done
IFS=$SAVEIFS; set +f
上面假设 GNUfind
并且文件名不包含换行符。
答案3
find . -name \*.mp3 -maxdepth 1 -print0 | shuf -z | while IFS= read -d '' -r l; do printf %s\\n "$l"; done
- -maxdepth、-print0、shuf 和 read -d 不是由 POSIX 定义的。 shuf 是 coreutils 的一部分。
- read 从行首和行尾去除 IFS 中的字符。 -r 禁用反斜杠的解释。
-d ''
是相同的-d $'\0'
。
或者,如果路径不包含换行符或反斜杠,并且它们不以 IFS 中的字符开头或结尾:
printf %s\\n *.mp3 | shuf | while read l; do printf %s\\n "$l"; done