You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含空格的目录名递归检查音频文件时长脚本问题求助

含空格的目录名递归检查音频文件时长脚本问题求助

嗨,James!你的问题其实是bash脚本里处理含空格文件名/目录名的经典坑,我来帮你梳理下问题根源和解决办法~

首先明确你的问题:你写的递归检查音频时长的脚本,在目录名不含空格时运行正常,但遇到像“dir 1”这种带空格的目录时,脚本会把目录名拆成“dir”和“1”两个独立的变量值,导致后续cd命令出错。你的原脚本如下:

#!/bin/bash

for dir in $(find . -type d); do

cd $dir

for file in *.ogg *.wav *.mp3

do

duration=$(ffprobe "$file" 2>&1 | awk '/Duration/ { print $2 }')

echo -e "$duration\t$file"

done | sort -n

cd - > /dev/null

done

问题根源

你用for dir in $(find . -type d)这种写法时,shell会默认把find输出的内容按空格、制表符、换行符分割成多个元素,所以带空格的目录名会被拆成好几段,自然就没法正确识别完整的目录路径了。

两种可靠的解决方案

方案一:用find -exec直接处理(更简洁)

让find直接帮你处理目录跳转,避开手动处理目录名的麻烦,写法更简洁:

#!/bin/bash

find . -type d -exec bash -c '
    cd "$0"
    for file in *.ogg *.wav *.mp3; do
        # 过滤掉通配符未匹配到文件的情况
        [[ -f "$file" ]] || continue
        duration=$(ffprobe "$file" 2>&1 | awk '\''/Duration/ { print $2 }'\'')
        echo -e "$duration\t$file"
    done | sort -n
' {} \;

方案二:用while read配合find -print0(兼容性更强)

如果需要更灵活的逻辑扩展,推荐用这种方式:find的-print0参数会让输出的目录名以空字符分隔,再用while read -d ''读取,完全避免分割错误:

#!/bin/bash

find . -type d -print0 | while IFS= read -r -d '' dir; do
    # 进入目录失败时直接跳过,避免脚本卡死
    cd "$dir" || continue
    for file in *.ogg *.wav *.mp3; do
        [[ -f "$file" ]] || continue
        duration=$(ffprobe "$file" 2>&1 | awk '/Duration/ { print $2 }')
        echo -e "$duration\t$file"
    done | sort -n
    cd - > /dev/null
done

额外的小优化

我在脚本里加了[[ -f "$file" ]] || continue这一行——当某个目录里没有匹配的音频文件时,通配符会原样输出(比如*.ogg),这一步可以帮你过滤掉这些无效的“文件名”,避免ffprobe报错。另外,所有涉及文件名/目录名的变量都用双引号""包裹起来,这是bash里处理特殊字符的基本操作哦~

这样修改后,不管目录名里有空格、下划线还是其他特殊字符,脚本都能正常运行啦!

备注:内容来源于stack exchange,提问作者JamesB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 08:57:48