如何使用“更改目录”选项使tar遍历工作


8

我有followin目录结构:

base/
   files/
   archives/
   scripts/

我想一个脚本来运行的scripts/,压缩文件,那场比赛results.*.logfiles/为gzip压缩tar归档文件中archives/

我正在尝试以下命令:

tar czfC ../archives/archive.tar.gz ../files results.*.log

但是我明白了

tar: results.*.log: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

tar czfC ../archives/archive.tar.gz ../files results.a.log

可以正常工作。也

tar czf ../archives/archive.tar.gz ../files/results.*.log

以我想要的方式工作,除了它files/在文件中添加了前缀并且还发出警告:

tar: Removing leading `../' from member names

因此,我的结论是,tar使用该-C选项时,globbing无法正常工作。关于如何以一种简单的方式进行这项工作的任何建议?

Answers:


3

编写起来更方便:

(cd ../files && tar cf - results.*.log) | 
  gzip -9 > ../archives/archive.tar.gz

cd发生这种情况之前,该glob仍将在当前目录中解释。
vonbrand

1
@vonbrand,不,当然不会。&&就像;或换行符,它将两个命令分开。就像说,运行之后cd,任何glob都会扩展先前目录中的文件。
斯特凡Chazelas

你是对的。一个人永远不会完成学习。
vonbrand 2013年

5

没有“ tar遍历”,遍历是由外壳完成的。而且,shell不知道tar -C somedir将在其中进行工作somedir,所有glob都会在当前目录中展开。


实际上,如果results.a.log运行脚本的目录中存在该脚本,则该脚本可以工作。但是我不明白为什么会这样,因为-C代表更改目录,所以当前目录应该是带有的目录results.a.log。我无法接受您的回答,因为您没有提供解决方案。
Yuval 2013年

2
Shell接受命令,在当前目录中扩展glob,从上述内容制造参数,然后启动tar程序,该程序将在更长时间后更改目录。抱歉,无法“解决”您的问题。唯一的出路是进入要在其中进行glob的目录,或在目录中进行glob并将其结果保存在文件或变量中。
vonbrand 2013年

1

您可以通过创建前缀文件之前删除前缀findtar进行通配并忽略“更改目录”选项files/

--no-recursion选项tar是可选的,因为没有目录将被存档。

cd base/scripts

# gnutar
# printf '%s\000' ../files/results.*.log |  # find alternative
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   gnutar --transform="s|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
gnutar -tf ../archives/archive.tar.gz | nl
gnutar -xzf ../archives/archive.tar.gz

# bsdtar
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   bsdtar -s "|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
bsdtar -tf ../archives/archive.tar.gz | nl
bsdtar -xzf ../archives/archive.tar.gz

0

我终于用了

tar czfC ../archives/archive.tar.gz ../files `find ../files/results.*.log -printf "%f\n"`

尽管这可能对您有用,但这是一种非常复杂的方法。此外,它不适用于包含特殊字符(例如空格)的文件名。使用答案中提出的一种理智的方法。
吉尔斯(Gillles)“所以-别再邪恶了”

0

这样做的方法是编写如下内容:

#!/bin/sh

cd ../files
tar zcf ../archives/archive.tar.gz results.*.log
cd ../scripts

0

不是tar起作用了,而是外壳。您首先要告诉外壳程序进行globing,然后告诉tar更改目录。由于tar正在接收相对于原始目录的文件名列表,因此这不起作用。

到目前为止,最简单的解决方案是让Shell更改目录。互动地:

cd ../files
tar czf ../archives/archive.tar.gz  results.*.log
cd -

在脚本中:

(
  cd ../files &&
    tar czf ../archives/archive.tar.gz  results.*.log
)

要么

(
  cd ../files &&
    tar czf -  results.*.log
) >../archives/archive.tar.gz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.