如何在 bash 脚本中保留文件夹结构?

How to retain folder structure in bash scripting?

我做了一个程序来转换音乐的比特率。程序如下..

for f in *.mp3 ;
  do lame --mp3input -b $bitrate "$f" $path_to_destination/"$f" ;
done;

但这只适用于一个文件夹;我有不同文件夹中的音乐。如何修改代码,使其可以递归地进行转换,同时在输出中保留文件夹结构?

find . -type f -name '*.mp3' | while IFS= read -r src
do
   dst="$path_to_destination/$src"
   mkdir -p $(dirname "$dst")
   lame --mp3input -b $bitrate "$src" "$dst"
done

如果你有足够新的 Bash(4.3 版可用;3.x 版不可用),你可以使用:

shopt -s globstar nullglob
for file in *.mp3 **/*.mp3
do
    lame --mp3input -b $bitrate "$file" "$path_to_destination/$file"
done

globstar 选项意味着 ** 符号递归工作; nullglob 选项意味着如果在任何子目录(或没有子目录)中没有 .mp3 文件,则不会生成任何内容,而是默认情况下会发生的名称 **/*.mp3 .

因为这使用了 globbing,所以即使路径或文件名包含空格、换行符或其他笨拙的字符也是安全的。

如果子目录不一定存在于$path_to_destination下,那么您需要创建它们。添加:

mkdir -p $(dirname "$path_to_destination/$file")

在调用 lame 之前。这将在通向目标文件的路径上创建所有缺失的目录(如果所有目录都已存在则不会出错),留下 lame 在该目录中创建文件。