디렉토리의 파일을 무작위로 반복

디렉토리의 파일을 무작위로 반복

현재 디렉터리의 모든 파일을 무작위로 탐색 for track in *.mp3; do하도록 어떻게 변경할 수 있나요 ?.mp3

답변1

참고로 에서는 zshglobbing 한정자를 사용하여 glob이 확장되는 순서에 영향을 줄 수 있습니다 o. 예를 들어 *.mp3(om)수정 시간을 기준으로 정렬합니다. 함수를 사용하여 자신만의 정렬 순서를 정의할 수 있습니다.

를 사용하면 파일은 파일 이름을 기준으로 하는 것이 아니라 파일 이름이 지정된 변수( 파일 이름 도 수신함 ) *.mp3(o+foo)에서 함수가 foo반환한 값을 기준으로 정렬됩니다. 예를 들어:$REPLYfoo$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

위의 내용은 GNU를 가정 find하고 파일 이름에 개행 문자가 포함되어 있지 않습니다.

답변3

find . -name \*.mp3 -maxdepth 1 -print0 | shuf -z | while IFS= read -d '' -r l; do printf %s\\n "$l"; done

  • -maxlength, -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

관련 정보