关于bash:来自不同目录的tar文件,没有路径

Tar files from different directories without paths

1
2
3
4
5
6
7
8
9
10
11
I have a following structure:

-folder1
   -folder2
     -file1
     -file2
   -folder3
     -folder4
       -folder5
         -file3
         -file4

使用bash,我需要在实际目录中创建一个.tar归档文件,其中包含4个文件(file1、file2、file3、file4)。我试过的所有东西都会用它们的路径创建一个文件存档。我需要的是一个文件档案,其中必须包含:

1
2
3
4
file1
file2
file3
file4


如果您知道文件名及其目录,您可以使用-C/--directory选项让tar在处理参数时更改其操作目录。

所以这个命令:

1
tar -cf files.tar.gz -C folder1/folder2 file1 file2 -C ../folder3/folder4 file3 file4

将在当前目录中创建files.tar.gz,其中只包含文件。

您可以从find输出或类似的输出中自动创建必要的命令行参数,如果需要的话,只需编写一点脚本。

(不能在文件参数位置使用像folder1/folder2/*这样的globs,因为这些文件名中的路径会导致tar找不到它们。您可以在该位置使用$(ls folder1/folder2/),但对于许多有效的文件名来说,这显然不安全。)


不必创建笨拙的链接或不使用通配符,您可以创建存档,然后更改目录并附加到它(使用r选项),如下所示:

1
2
3
tar cvf ~/archive.tar file*                             # make initial tarball
(cd folder2 && tar rvf ~/archive.tar file* )            # append others to it
(cd folder3/folder4 && tar -rvf ~/archive.tar file*)    # and more...

请注意,我在子壳中执行上述操作,以避免之后不得不返回cd


由于EDOCX1[1]是为存储目录结构而构建的,如果不保留目录结构,则必须在…

为此,可以创建临时目录以在一个uniq级别存储符号链接:

1
2
3
4
5
6
tmpdir=$(mktemp -d /tmp/tardir-XXXXXX)
find $PWD -type f -exec ln -st $tmpdir {} +
cd $tmpdir
tar -chvf /tmp/myarchive.tar *
cd -
rm -fR $tmpdir

Nota:

  • $PWD迫使find将整个路径连接到临时目录。
  • -h选项到tar告诉他存储指向文件而不是symlink。

在不创建任何临时目录的情况下尝试此操作:

1
find .type f  | pax -wv -s '/.*\///g' -f file.tar

来自man pax

pax — read and write file archives and copy directory hierarchies


简单的解决方案是创建到/tmp的硬链接,然后从那里存档,如下所示:

1
2
3
4
5
6
7
8
9
mkdir /tmp/allfiles
find /home/user/folder1 -type f | while read file
do
ln $file /tmp/allfiles
done
cd /tmp/allfiles
tar cvf /tmp/myarchive.tar *
rm /tmp/allfiles/*
rmdir /tmp/allfiles

注意,只有当/tmp和~/folder1都在同一个文件系统上时,硬链接才会工作。这只会建立链接,而不会消耗额外的磁盘空间。

您可以先删除rm命令。脚本中的类型可能会产生错误结果:-)。