저는 현재 모든 flac 파일을 mp3 파일로 변환하는 작은 스크립트를 작성하려고 합니다. 그러나 모든 음악 폴더에 걸쳐 재귀를 설정하려고 하면 몇 가지 문제가 발생합니다. 스크립트가 계속 현재 디렉터리(.)로 반복됩니다.
이것이 내가 현재 가지고 있는 것입니다:
#!/bin/bash
#---
# flacToMp3: Converts FLAC files in my originalFLAC folder into mp3 files
# and places them in an identical folder structure in my Music
# folder.
#---
function enterDIR {
for DIR in "$(find . -maxdepth 1 -type d)"; do #recurse into every directory below top-level directory
if [ "$DIR" == "." ]; then #avoid current directory infinite loop
continue
fi
cd "$DIR/"
enterDIR
done
createDirectory
convertFLAC
}
function createDirectory {
#recreate directory structure in Music folder
curDir="$pwd"
newDir=${curDir/originalFLAC/Music}
mkdir -p $newDir
}
function convertFLAC {
#convert each flac file in current directory into an mp3 file
for FILE in "$(find . -maxdepth 1 -type f)"; do #loop through all regular (non-directory) files in current directory
if [ "${FILE: -5}" == ".flac" ]; then #if FILE has extension .flac
ffmpeg -i "$FILE" -ab 320k -map_metadata 0 "${FILE%.*}.mp3"; #convert to .mp3
mv -u "${FILE%.*}.mp3" $newDir
else #copy all other files to new directory as-is
cp -ur "$FILE" $newDir
fi
done
}
enterDIR
이 스크립트는 Bash를 이제 막 시작했기 때문에 매우 투박합니다. 문제(또는 적어도 내가 문제라고 생각하는 것)는 해당 if [ "$DIR" == "." ]; then
줄에서 발생합니다. 스크립트를 실행할 때 내 출력을 보면 필터링되지 않는 것 같습니다.
현재 디렉터리를 필터링(무시)하는 방법은 무엇입니까?
답변1
find
options 을 사용하여 필터링할 수 있습니다 -mindepth
. 이와 같이:
function enterDIR {
find . -mindepth 1-maxdepth 1 -type d | while read DIR ;
do
#recurse into every directory below top-level directory
cd "$DIR/"
enterDIR
done
createDirectory
convertFLAC
}
그러나 전체 스크립트는 좋은 솔루션처럼 보이지 않습니다.
내가 올바르게 이해했다면 전체 디렉토리 트리를 탐색하고, 새 디렉토리를 만들고, flac를 mp3로 변환하고(있는 경우) flac가 아닌 모든 파일을 새 디렉토리에 복사하고 싶을 것입니다. 나는 이렇게 할 것이다:
find . -mindepth 1 -type -d -exec mkdir -p {}/originalFLAC/Music \+
find . -type f -iname "*.flac" -exec ffmpeg -i {} -ab 320k -map_metadata 0 {}.mp3 \;
find . -type f ! -iname "*.flac" | while read file ; do cp -v "$file" "$(dirname "$file")"/originalFLAC/Music/ ; done
답변2
이것을 교체해 보세요
for DIR in "$(find . -maxdepth 1 -type d)"
이것으로
for DIR in "$(find . -maxdepth 1 -type d | grep -v "\.$")"
.
정규식에서 "모든" 단일 문자로 해석됩니다. 따라서 백슬래시로 이스케이프 처리해야 합니다. 또한 모든 줄은 점 문자로 시작하므로 점과 점만 포함된 줄을 찾아야 합니다. 따라서 줄 끝 문자 $
.
이 시점에서는 if
다음 블록이 필요하지 않습니다.
if [ "$DIR" == "." ]; then #avoid current directory infinite loop
continue
fi