Linux 连接tar文件,以便在不使用-i选项的情况下打开生成的tar

Linux 连接tar文件,以便在不使用-i选项的情况下打开生成的tar,linux,bash,tar,Linux,Bash,Tar,我得到了包含很多非常小的JSON文件的tar档案。每天我都会得到一个新的焦油档案。现在我想把每日的tar档案合并成每年一次的tar档案,并对其进行压缩。我使用以下bash脚本来实现这一点: tar -cf "/mnt/archive/archive - 2020.tar" --files-from /dev/null for f in /mnt/data/logs/2020/logs-main-2020-??-??.tar do tar -n --concatenat

我得到了包含很多非常小的JSON文件的tar档案。每天我都会得到一个新的焦油档案。现在我想把每日的tar档案合并成每年一次的tar档案,并对其进行压缩。我使用以下bash脚本来实现这一点:

tar -cf "/mnt/archive/archive - 2020.tar" --files-from /dev/null
for f in /mnt/data/logs/2020/logs-main-2020-??-??.tar
do
    tar -n --concatenate --file="/mnt/archive/archive - 2020.tar" $f
done

pxz -T6 -c "/mnt/archive/archive - 2020.tar" > "/mnt/archive/archive - 2020.tar.xz"
rm "/mnt/archive/archive - 2020.tar"
这是可行的,但是主tar越大,tar文件的连接速度就越慢

我可以使用
cat
指令简单地将所有tar添加到一起,但是生成的归档包含原始tar的所有归档结束空标记。因此,结果tar必须使用
-i
选项打开,该选项不适用于处理结果tar的系统

我如何连接tar文件而不需要缓慢的tar concats,并且仍然可以创建一个有效的tar文件,而中间没有空值?我可以做一些猫,去焦油,再焦油,压缩管道吗

  • 我在输入tars的JSON文件名中没有任何空间字符,比如换行符
  • 我在CentOS 7上使用GNU tar v1.26
  • 每个输入tar大约为1GB,因此无法将它们保存在内存中
  • 无需检查输出tar中是否存在重复条目。创建输入tar的方式确保它们没有重复的JSON文件

两种基于perl的方法:

首先,一个脚本使用core
Archive::Tar
模块读取现有的Tar文件并创建一个新的Tar文件(由于该模块的限制,它必须在写入之前将合并的目标Tar文件的数据一次保存在内存中;可能存在大量数据的问题):

#/usr/bin/env perl
使用警告;
严格使用;
使用功能qw/say/;
使用归档::Tar;
#第一个参数是要创建的新tar文件,其余参数是要创建的tar文件
#从中复制文件。
die“用法:$0 DESTFILE SOURCEFILE…\n”,除非@ARGV>=2;
我的$destfile=shift;
my$dest=Archive::Tar->new;
foreach my$文件(@ARGV){
my$src=Archive::Tar->iter($file)或退出1;
说“添加$file的内容”;
而(my$file=$src->()){
我的$name=$file->full_路径;
说“\t$name”;
$dest->add_data($name,$file->get_content),
{mtime=>$file->mtime,
大小=>$file->size,
模式=>$file->mode,
uid=>$file->uid,
gid=>$file->gid,
类型=>$file->type,
devmajor=>$file->devmajor,
devminor=>$file->devminor,
linkname=>$file->linkname
})
或出口1;
}
}
$dest->write($destfile)或退出1;
说“写了$destfile”;
用法:

perl tarcat.pl”/mnt/archive/archive-2020.tar”/mnt/data/logs/2020/logs-main-2020-??.tar

或者使用一行程序(如果提供,则通过OS package manager或最喜爱的CPAN客户端安装;不确定其内存限制):

perl-MArchive::Tar::Merge-e'
归档::Tar::合并->新建(dest_tarball=>$ARGV[0],
source_tarballs=>[@ARGV[1..$#ARGV]])->合并
“/mnt/archive/archive-2020.tar”/mnt/data/logs/2020/logs-main-2020-??.tar

也许可以研究其他归档格式,如7z或zip(浏览手册页,它有一个看起来非常有前途的
复制操作)?或者将所有日常归档文件解压到一棵树中,然后一次将其全部加上焦油?(我还考虑使用zstandard而不是xz进行压缩;它的速度明显更快,压缩率几乎与xz相同)。感谢您的建议,但由于合并的大小,在内存中执行此操作不是一个选项。