根据命令行中的文件夹递归地将文件压缩为 .cbz 文件

根据命令行中的文件夹递归地将文件压缩为 .cbz 文件

我正在尝试弄清楚如何编写脚本来自动从 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 1findtoplevel/comicswhile$dir$dir-type f-mindepth 1 -maxdepth 1findwc$numcbz

注意:存档将包含文件的完整路径(通过解压一个文件进行测试),如果您不想要这个,您可能需要提供-j此选项。请参阅zipman zip

相关内容