tar 使用名称为 space 的 files/folders 输入列表
tar using input list of files/folders with space in their names
目录中有带空格的文件和子文件夹:
$ find ./test
./test
./test/testdir
./test/testdir/file 1 2 3
./test/testdir 2 3 4
./test/testdir 2 3 4/file 5 6 7
./test/testfile
./test/otherdir
./test/otherdir/otherfile
./test/otherfile
$
这只是展示案例的测试文件夹示例,但在真实环境中,这是一个巨大的文件夹,包含数百个文件,总大小约为 . 100GB.
我有一个 zip 文件,其中包含上述文件夹中某些文件的更新。在解压缩更新文件之前,我想对每个将被此更新替换的文件进行选择性备份。
update.zip 文件中的文件是:
$ unzip -Z1 update.zip
testdir/
testdir/file 1 2 3
testdir 2 3 4/
testdir 2 3 4/file 5 6 7
testfile
$
Here is the command which I tried to do such backup which failed:
$ tar czvf backup_before_update.tgz -C ./test/ $(unzip -Z1 update.zip|grep -v \/$|sed -r 's/^/"/;s/$/"/'|paste -sd" ")
tar: "testdir/file: Cannot stat: No such file or directory
tar: 1: Cannot stat: No such file or directory
tar: 2: Cannot stat: No such file or directory
tar: 3": Cannot stat: No such file or directory
tar: "testdir: Cannot stat: No such file or directory
tar: 2: Cannot stat: No such file or directory
tar: 3: Cannot stat: No such file or directory
tar: 4/file: Cannot stat: No such file or directory
tar: 5: Cannot stat: No such file or directory
tar: 6: Cannot stat: No such file or directory
tar: 7": Cannot stat: No such file or directory
tar: "testfile": Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
$
当我手动执行“echo”和运行命令时,没有这样的错误:
$ echo tar czvf backup_before_update.tgz -C ./test/ $(unzip -Z1 update.zip|grep -v \/$|sed -r 's/^/"/;s/$/"/'|paste -sd" ")
tar czvf backup_before_update.tgz -C ./test/ "testdir/file 1 2 3" "testdir 2 3 4/file 5 6 7" "testfile"
$ tar czvf backup_before_update.tgz -C ./test/ "testdir/file 1 2 3" "testdir 2 3 4/file 5 6 7" "testfile"
testdir/file 1 2 3
testdir 2 3 4/file 5 6 7
testfile
$
我可以使用 eval,它也可以:
$ eval $(echo tar czvf backup_before_update.tgz -C ./test/ $(unzip -Z1 update.zip|grep -v \/$|sed -r 's/^/"/;s/$/"/'|paste -sd" "))
testdir/file 1 2 3
testdir 2 3 4/file 5 6 7
testfile
$ eval $(echo tar czvf backup_before_update.tgz -C ./test/ $(unzip -Z1 update.zip|grep -v \/$|sed -r 's/^/"/;s/$/"/'))
testdir/file 1 2 3
testdir 2 3 4/file 5 6 7
testfile
$
即使所有给定的文件名都用双引号引起来,为什么第一个命令也会失败?
当您使用 set -x
打开调试(并使用 set -
关闭)时,您会看到 $(...)
的结果使用空格作为分隔符拆分为参数。在你的情况下(没有带换行符的文件名)当你创建一个文件列表时,你几乎完成了,每个文件都在一行上。
GNU tar
可以使用 -T
选项
从文件中读取
-T, --files-from=FILE
Get names to extract or create from FILE.
Unless specified otherwise, the FILE must contain a list of names separated by
ASCII LF (i.e. one name per line). The names read are handled the same way as
command line arguments.
当您希望将 cmd
的结果作为文件处理时,您可以使用结构 <(cmd)
。
tar czvf backup_before_update.tgz -C ./test/ -T <(unzip -Z1 update.zip|grep -v \/$)
目录中有带空格的文件和子文件夹:
$ find ./test
./test
./test/testdir
./test/testdir/file 1 2 3
./test/testdir 2 3 4
./test/testdir 2 3 4/file 5 6 7
./test/testfile
./test/otherdir
./test/otherdir/otherfile
./test/otherfile
$
这只是展示案例的测试文件夹示例,但在真实环境中,这是一个巨大的文件夹,包含数百个文件,总大小约为 . 100GB.
我有一个 zip 文件,其中包含上述文件夹中某些文件的更新。在解压缩更新文件之前,我想对每个将被此更新替换的文件进行选择性备份。
update.zip 文件中的文件是:
$ unzip -Z1 update.zip
testdir/
testdir/file 1 2 3
testdir 2 3 4/
testdir 2 3 4/file 5 6 7
testfile
$
Here is the command which I tried to do such backup which failed:
$ tar czvf backup_before_update.tgz -C ./test/ $(unzip -Z1 update.zip|grep -v \/$|sed -r 's/^/"/;s/$/"/'|paste -sd" ")
tar: "testdir/file: Cannot stat: No such file or directory
tar: 1: Cannot stat: No such file or directory
tar: 2: Cannot stat: No such file or directory
tar: 3": Cannot stat: No such file or directory
tar: "testdir: Cannot stat: No such file or directory
tar: 2: Cannot stat: No such file or directory
tar: 3: Cannot stat: No such file or directory
tar: 4/file: Cannot stat: No such file or directory
tar: 5: Cannot stat: No such file or directory
tar: 6: Cannot stat: No such file or directory
tar: 7": Cannot stat: No such file or directory
tar: "testfile": Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
$
当我手动执行“echo”和运行命令时,没有这样的错误:
$ echo tar czvf backup_before_update.tgz -C ./test/ $(unzip -Z1 update.zip|grep -v \/$|sed -r 's/^/"/;s/$/"/'|paste -sd" ")
tar czvf backup_before_update.tgz -C ./test/ "testdir/file 1 2 3" "testdir 2 3 4/file 5 6 7" "testfile"
$ tar czvf backup_before_update.tgz -C ./test/ "testdir/file 1 2 3" "testdir 2 3 4/file 5 6 7" "testfile"
testdir/file 1 2 3
testdir 2 3 4/file 5 6 7
testfile
$
我可以使用 eval,它也可以:
$ eval $(echo tar czvf backup_before_update.tgz -C ./test/ $(unzip -Z1 update.zip|grep -v \/$|sed -r 's/^/"/;s/$/"/'|paste -sd" "))
testdir/file 1 2 3
testdir 2 3 4/file 5 6 7
testfile
$ eval $(echo tar czvf backup_before_update.tgz -C ./test/ $(unzip -Z1 update.zip|grep -v \/$|sed -r 's/^/"/;s/$/"/'))
testdir/file 1 2 3
testdir 2 3 4/file 5 6 7
testfile
$
即使所有给定的文件名都用双引号引起来,为什么第一个命令也会失败?
当您使用 set -x
打开调试(并使用 set -
关闭)时,您会看到 $(...)
的结果使用空格作为分隔符拆分为参数。在你的情况下(没有带换行符的文件名)当你创建一个文件列表时,你几乎完成了,每个文件都在一行上。
GNU tar
可以使用 -T
选项
-T, --files-from=FILE
Get names to extract or create from FILE.
Unless specified otherwise, the FILE must contain a list of names separated by
ASCII LF (i.e. one name per line). The names read are handled the same way as
command line arguments.
当您希望将 cmd
的结果作为文件处理时,您可以使用结构 <(cmd)
。
tar czvf backup_before_update.tgz -C ./test/ -T <(unzip -Z1 update.zip|grep -v \/$)