我有几个包含数千个文件的文件夹,每个文件夹的大小大约为 3 - 10GB。现在,我想将这些文件打包到文件夹内,每个 tar 文件的大小应约为 1GB。之后,我想使用 Python 来处理这些 tar 文件。
#!/bin/bash
dirlist=$(find $1 -mindepth 1 -maxdepth 1 -type d)
stored_date=$(date +%Y-%m-%d --date="-1 day")
#stored_date='2019-10-23'
for dir in $dirlist
do
(
cd $dir
tar_file=${PWD##*/}
tar_file="${tar_file}_${stored_date}.tar"
echo "${tar_file}"
tar -c $stored_date*.html --tape-length=1000M -f ${tar_file} --remove-files
)
done
它可以很好地创建 1GB 块 - 但使用“--tape-length”选项时,Python 会遇到各种问题
tarfile.ReadError:数据意外结束
(另外:我也想使用 Python 来处理在 tar 存档边缘分割的文件)
Linux 有解决这个问题的方法吗?我发现 star 而不是 tar,但还没有尝试过 - 如果可能的话,我更愿意使用标准 tar。
答案1
在每个目录循环中嵌套第二个循环以在将每个文件附加到 tar 文件之前跟踪每个文件的大小怎么样?这是我的意思的示意性伪代码:
max_size=$((1024*1024*1024))
total_size=0
for dir in $dirlist ; do
for foo in $dir/*; do
this_size="$(stat -c"%s" $foo)"
if [ $(($total_size + $this_size)) -le $max_size ] ; then
tar --append ... $foo
total_size="$(($total_size + $this_size))"
else
# start new tar file here
tar -c ... $foo
total_size="$this_size"
fi
done
done
答案2
据我所知,python 不理解 tar 格式,因此您可能喜欢使用可能与 tar 存档标准不 100% 兼容的 tar 存档模块。这是一个需要考虑的重要事项,有许多半生不熟的 tar 实现通常仅支持官方功能集的子集。
我建议在不进入模式的情况下使用该star
选项。这可以防止在中间分割文件,但无法归档大于指定磁带大小的文件。-tsize
star
multi volume
star
如果默认 shell“sh”在支持“$((expr))”方面符合 POSIX,否则将“sh -c”替换为“ksh -c”或类似的。
...怎么样:
cd /tmp
star -C path/to/archivedir -c tsize=1G \
new-volume-script='cd /tmp;sh -c "mv vol-last.tar vol\$((\$1-1)).tar" script' \
f=vol-last.tar .
这会将创建的 TAR 存档保留在 /tmp 中。您需要手动将 vol-last.tar 重命名为最终预期的卷号。我可能会考虑增强 star 以将新卷脚本运行到每个存档的末尾,包括最后一个。