如何在 bash 中过滤掉当前目录('.')?

如何在 bash 中过滤掉当前目录('.')?

我目前正在尝试编写一个小脚本来将所有 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您可以使用选项过滤它-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

相关内容