随机遍历目录中的文件

随机遍历目录中的文件

如何更改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

相关内容