![如何重复解压缩 tar 本身中的 tar 文件](https://linux22.com/image/161807/%E5%A6%82%E4%BD%95%E9%87%8D%E5%A4%8D%E8%A7%A3%E5%8E%8B%E7%BC%A9%20tar%20%E6%9C%AC%E8%BA%AB%E4%B8%AD%E7%9A%84%20tar%20%E6%96%87%E4%BB%B6.png)
我有一个 tar 文件,已经被 tar 了很多次。它遵循类似的结构:
1000.tar
|
--- filler.txt (random text)
999.tar
|
--- filler.txt
998.tar
...
如何编写命令/代码来获取 tar 结构的最终 .txt?我可以手动完成此操作tar -xf 1000.tar
,但使用代码更有效。
我想代码应该是这样的:
for i in range 1000, 1:
tar -xf string(i) + ".tar"
答案1
这个简单的bash
for 循环应该可以满足您的需要:
for i in {1000..1}; do tar -xf $i.tar; done
答案2
这是一种递归方法,不需要您提前知道 tarball 的文件名。将文件放在不包含任何其他内容的目录中。然后,假设父存档中包含的所有 tarball 都有.tar
扩展名,您可以简单地执行以下操作:
file=(*tar); while [[ -e $file ]]; do tar xf "$file"; rm "$file"; file=(*tar); done
解释
file=(*tar);
:设置变量$file
以包含文件名。*tar
运行该程序的目录中应该只有一个与 glob 匹配的文件。while [[ -e $file ]]; do
: 当$file
存在时...tar xf $file; rm "$file"; file=(*tar);
:解压 的当前值$file
,然后删除刚刚解压的 tarball,最后将变量设置$file
为目录中现在唯一的新 tar 文件的名称。
这是一个更直接的方法(谢谢@kusalananda!)。我tar
使用以下命令制作了存档:
$ cat file
This is the text!
$ file=file; for i in {1..1000}; do tar cf $i.tar $file; file=$i.tar; done
所以这是一个名为的文件file
,其中包含文本This is the text!\n
.已经file
涂了 1000 次柏油,现在我们已经有了1000.tar
。我们可以使用以下命令打印原始文本:
$ awk -F'\0' '/[^\0]/{print $(NF)}' 1000.tar
This is the text!
请注意,这实际上并不是原文。原来的换行符被 吃掉tar
但被 取代awk
。要从存档中获取真正的价值,您需要(最后$
是我的提示,没有换行符):
$ awk -F'\0' '/[^\0]/{printf "%s", $NF}' 1000.tar
This is the text!$
在这种特殊情况下,我还可以通过告诉awk
打印最后一个字段 ( $NF
) 以及最后一个字段之前的第 438 个字段来重新创建文件名:
awk -F'\0' '/[^\0]/{print $(NF) >$(NF-438)}' 1000.tar
file
这就用原来的内容创建了一个新的。所以和提取是一样的。但是,我不知道这是否-428
是一个神奇的数字。tar
似乎在其存档中添加了多个 NULL,所以我发现通过运行:
$ awk -F'\0' '{for(i=1;i<=NF;i++){ if($i ~ /file/){print i,NF-i}}}' 1000.tar
434674 438
这告诉我字段 434674 有内容file
,即最后一个字段之前的 438 个字段。
如果您awk
支持gsub
,您可以通过以下方式使其更通用:
awk -F'\0' '/[^\0]/{gsub(/\0+/,"\0"); print $NF > $(NF-11)}' 1000.tar