使用 find 处理 bash 脚本的文件夹名称(包含空格和 ')失败

问题描述 投票:0回答:1

使用 bash 版本 5.*

我创建了一个脚本,该脚本创建一个将在给定文件夹中播放视频和/或音频文件的脚本,使用此函数创建的播放多媒体文件脚本

ffprobe -hide_banner 2>&1 "$*" |grep Stream|grep "Video:" >/dev/null
if [ $? -eq 0 ]; then
    # return zero -> video file: default
    ffplay -autoexit -hide_banner -fs -i "$*"
else
    # return non-zero -> audio only - adjusting…
    ffplay -autoexit -hide_banner -showmode waves -x 500 -y 150 -i "$*"
fi
}

创建这些脚本的脚本称为 make-ffplay-script,当给定的文件夹名称末尾有“/”时,不会出现问题,但当给定的文件夹名称开头有“./”时,会出现问题给定文件夹名称;它仅适用于相对路径,因此包含视频和/或音频文件的文件夹“foldername/”可以移动到任何地方,并且相应的foldername.sh可以与文件夹一起移动/复制,并执行./foldername.sh将播放“foldername/”中的文件无论是“foldername/”和“foldername.sh”都是 - 只要“foldername/”和“foldername.sh”位于同一文件夹中。

到目前为止一切都很好,只要我为每个文件夹手动调用脚本 make-ffplay-script 即可。当文件夹名称包含空格时使用“单”或“双”引号或 \ 进行转义时,我的脚本 make-ffplay-script 可以正确处理文件夹名称。当文件夹名称包含 ' (单引号字符)时,我通过 "" 或 \ 进行转义;这些类型的文件夹名称也有效。 包含“(双引号字符)的文件夹/文件名不存在,包含换行符或空字节字符的文件夹名称也不存在。

现在我的问题是,我想使用“find . -type d -maxdepth 1 -mindepth 1”作为当前目录中的文件夹列表(无子文件夹),并以某种方式将其提供给我的 make-ffplay-script为所有文件夹创建脚本;尝试了几种转义空格(或 ' )的方法,但都失败了。

我创建了虚拟文件夹,其中包含 dummy.mp3 文件,以测试是否一切正常:

r@rava:/tmp/test$ mkdir "testdir" "testdir with space" "testdir's space"
r@rava:/tmp/test$ touch "testdir/dummy.mp3" "testdir with space/dummy.mp3" "testdir's space/dummy.mp3"
r@rava:/tmp/test$ find .
.
./testdir's space
./testdir's space/dummy.mp3
./testdir with space
./testdir with space/dummy.mp3
./testdir
./testdir/dummy.mp3

单独使用“find .-type d -max深度 1 -min深度 1”时,find 的结果按预期工作:

r@rava:/tmp/test$ find . -type d -maxdepth 1 -mindepth 1 
./testdir's space
./testdir with space
./testdir

然后我尝试使用此处答案采用的解决方案,但失败了:

r@rava:/tmp/test$ for d in $(find . -type d -maxdepth 1 -mindepth 1); do echo make-ffplay-script $d >> myfindloop.sh; done
r@rava:/tmp/test$ cat myfindloop.sh 
make-ffplay-script ./testdir's
make-ffplay-script space
make-ffplay-script ./testdir
make-ffplay-script with
make-ffplay-script space
make-ffplay-script ./testdir

r@rava:/tmp/test$ rm myfindloop.sh 

r@rava:/tmp/test$ for d in $(find . -type d -maxdepth 1 -mindepth 1); do echo make-ffplay-script \""$d"\" >> myfindloop.sh; done
r@rava:/tmp/test$ cat myfindloop.sh 
make-ffplay-script "./testdir's"
make-ffplay-script "space"
make-ffplay-script "./testdir"
make-ffplay-script "with"
make-ffplay-script "space"
make-ffplay-script "./testdir"

r@rava:/tmp/test$ rm myfindloop.sh 

r@rava:/tmp/test$ for d in $(find . -type d -maxdepth 1 -mindepth 1); do echo make-ffplay-script "$d" >> myfindloop.sh; done
r@rava:/tmp/test$ cat myfindloop.sh 
make-ffplay-script ./testdir's
make-ffplay-script space
make-ffplay-script ./testdir
make-ffplay-script with
make-ffplay-script space
make-ffplay-script ./testdir

为什么使用不带引号的 $d 和带引号的 "$q" 会导致相同的错误?

必须做什么才能使我得到的 myfindloop.sh 看起来像这样:

make-ffplay-script "testdir's space"
make-ffplay-script "testdir with space"
make-ffplay-script "testdir"
bash shell find escaping whitespace
1个回答
0
投票

生成与所需

myfindloop.sh
文件等效的一种方法是:

for d in */ ; do printf 'make-ffplay-script %q\n' "${d%/}"; done > myfindloop.sh
© www.soinside.com 2019 - 2024. All rights reserved.