readarray 명령에서 find 출력의 일부를 바꿉니다.

readarray 명령에서 find 출력의 일부를 바꿉니다.

Docker 컨테이너에서 사용하려면 파일 목록(재생 목록)을 만들어야 합니다. 따라서 호스트 시스템의 파일 경로는 설치 경로가 아닙니다. 이제 이 문제를 해결하려고 하는데 문제가 좀 있습니다.

이것은 대체 항목을 추가하려는 스크립트입니다.

tdir="/mountingpoint"

readarray -d $'\0' listing < <(find "${fdir}"/*.mp3 -print0)
#for mixing up and write to file
listing=( $(shuf -e "${listing[@]}") )
printf "%s\n" "${listing[@]}" > "playlist.m3u"

일반적인 접근 방식은 사용하는 것입니다. sed하지만 함께 사용하는 데 약간의 어려움이 있습니다. 스크립트를 다음과 같이 수정해야 할 것 같은데 readarray -d $'\0' listing < <(find "${fdir}"/"${d}"/ -name "*.mp3" -print0 -exec sed -i "s/"$fdir"/"$tdir"/" {} \;) , 이로 인해 sed: -e expression #1, char 9: unknown option to `s' 디렉토리 이름에 있는 슬래시가 이 오류를 일으키는 것 같습니다. 하지만 결과를 확인하기 위해 변수를 폴더 이름으로 바꾸려고 시도했지만 아무 일도 일어나지 않았습니다(실행 시간이 길어지는 것을 제외하고). 없음은 출력 파일에 대체 항목이 없음을 의미합니다.

나는 누군가가 내 부족한 영어 실력을 지적하고 내가 뭘 잘못하고 있는지 힌트를 줄 수 있기를 바랍니다. 감사합니다

답변1

~처럼@이카루스가지다지적, 해당 -exec옵션은 여기서 의미가 없습니다. 빈 구분 파일에 sed 대체를 적용하려고 합니다.이름, 다음 이름에 나타날 가능성이 없는 sed 패턴 구분 기호를 사용합니다.

find "${fdir}/${d}" -name '*.mp3' -print0 | sed -z "s:$fdir:$tdir:"

IMHO, 파이프라인 내부에 셔플링을 포함하지 않을 이유가 없습니다.

find "${fdir}/${d}" -name '*.mp3' -print0 | sed -z "s:$fdir:$tdir:" | shuf -z

예를 들어 주어진

~$ find . -name '*.mp3'
./dir/1.mp3
./dir/2.mp3
./dir/3.mp3
./dir/4.mp3
./dir/5.mp3

그 다음에

~$ fdir=./dir; tdir='./new/dir'

~$ readarray -t -d '' listing < <(find . -name '*.mp3' -print0 | sed -z "s:$fdir:$tdir:" | shuf -z)

~$ printf '%s\n' "${listing[@]}"
./new/dir/3.mp3
./new/dir/1.mp3
./new/dir/4.mp3
./new/dir/2.mp3
./new/dir/5.mp3

답변2

zsh대신 사용하십시오 bash:

() {print -rC1 -- $tdir/$^@} $fdir/*.mp3(Noe['REPLY=$RANDOM']:t)

또는 문자도 포함하지도 $fdir않고 $tdir포함 하지도 않는다고 가정합니다 :.

print -rC1 -- $fdir/*.mp3(Noe['REPLY=$RANDOM']:s:$fdir:$tdir)

bash4.4+ 및 GNU shuf(또는 )를 사용하면 sort -zR언제든지 다음을 수행할 수 있습니다.

print0()  { [ "$#" -eq 0 ] || printf '%s\0' "$@"; }
println() { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }

readarray -td '' listing < <(
  shopt -s nullglob
  cd -P -- "$fdir" && print0 *.mp3 | shuf -z)
println "${listing[@]/#/$tdir}"

또는:

print0()  { [ "$#" -eq 0 ] || printf '%s\0' "$@"; }
println() { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }

readarray -td '' listing < <(
  shopt -s nullglob
  print0 "$fdir"/*.mp3 | shuf -z)
println "${listing[@]/#"$fdir"/$tdir}"

동등한 것으로.

관련 정보