我正在尝试弄清楚如何编写脚本来自动从 OSX 上的文件夹中的图像创建 .cbz 文件。
我的目录树将如下所示:
/toplevel/
cbz/
comics/
Comic1/
comic1file1.jpg
comic1file2.gif
comic1file3.png
Comic2/
comic2file1.jpg
comic2file2.gif
Publisher/
Comic3/
comic3file1.jpg
comic3file2.gif
comic3file3.png
Comic4/
comic4file1.jpg
comic4file2.gif
我想要做的是运行一个脚本,该脚本将查找任何包含实际文件(而不是子文件夹)的文件夹并对其进行压缩,将其从 .zip 重命名为 .cbz,然后将 .cbz 文件移动到顶层的 /cbz 文件夹。任何包含子文件夹的文件夹都不应包含任何文件,因此这可能会有所帮助。另外,我不希望有比上面示例中显示的更深的子文件夹。
我所在的位置:此代码片段将查看文件夹并为每个子文件夹创建 .cbz 文件。
for dir in `ls`; do zip $dir $dir/*; mv $dir*zip $dir.cbz; done
我还发现了一些代码片段,它们会对所选文件夹下的每个子文件夹执行类似的操作,但我得到的结果各不相同,并且非常有兴趣了解仅对文件夹执行操作的最佳方法。另外,我不知道如何检查给定文件夹是否包含子文件夹或文件。(我想理想情况下我应该包括检查以查看是否同时存在两者,但对于我目前的情况来说,情况不应该如此。)有什么想法吗?
答案1
另一个略有不同的解决方案:
#!/bin/bash
find toplevel/comics -type d -not -empty -print0 | while IFS= read -r -d '' dir; do
if find "$dir" -maxdepth 1 -type f | read f; then
zip toplevel/cbz/"$(basename "$dir").cbz" "$dir"/*
fi
done
find … -print0 | while IFS= read -r -d '' file
是推荐模式迭代find
结果。执行简单的find … | while read file
操作即可,但前提是返回的文件名不包含换行符。ls
绝不建议进行解析。find "$dir" -maxdepth 1 -type f | read f
仅当目录中找到文件时才计算为真。它实现了与 @terdon 评估 输出的行数相同的目的find
。所有变量都需要用引号引起来,以防止文件名中的空格破坏参数。
答案2
首先,永远不要解析 ls 的输出。此外,您可以zip
为它将创建的存档指定任意名称,这样您就无需移动文件。试试这个:
find toplevel/comics/ -mindepth 1 -type d |
while read dir; do
num=$(find "$dir" -mindepth 1 -maxdepth 1 -type f | wc -l )
[ "$num" -gt "0" ] && zip toplevel/cbz/"$(basename $dir)".cbd "$dir"/*;
done
第一个find
命令搜索至少比给定路径 (子目录) 低一级 () 的目录toplevel/comics/
( )。这确保不会返回自身作为结果。查找的结果通过管道传输到循环,循环处理保存在变量中的每个结果。每个命令都搜索实际位于该目录中而不是子目录中的文件 ( )。返回的行数(这就是所做的)保存为,如果它大于 0,则压缩目录并将存档放入。type -d
-mindepth 1
find
toplevel/comics
while
$dir
$dir
-type f
-mindepth 1 -maxdepth 1
find
wc
$num
cbz
注意:存档将包含文件的完整路径(通过解压一个文件进行测试),如果您不想要这个,您可能需要提供-j
此选项。请参阅zip
man zip
。