현재 디렉터리의 모든 파일을 무작위로 탐색 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
위의 내용은 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