find 命令给出以下输出:
[root@localhost /]# 查找 var/log/-iname anaconda.* var/log/anaconda.log var/log/anaconda.xlog var/log/anaconda.yum.log var/log/anaconda.syslog var/log/anaconda.program.log var/log/anaconda.storage.log
与 tar 结合后显示以下输出:
[root@localhost /]# find var/log/-iname anaconda.*-exec tar-cvf file.tar {} \; var/log/anaconda.log var/log/anaconda.xlog var/log/anaconda.yum.log var/log/anaconda.syslog var/log/anaconda.program.log var/log/anaconda.storage.log
但在列出 tar 文件时,它只显示一个文件
[root@localhost /]# tar -tvf 文件.tar -rw------- root/root 208454 2012-02-27 12:01 var/log/anaconda.storage.log
我在这里做错了什么?
使用 xargs 我得到了这个输出:
[root@localhost /]# 查找 var/log/-iname anaconda.* | xargs tar -cvf file1.tar
第二个问题
打字时/在 var 前面,表示find /var/log
为什么它会给出这个消息tar:从成员名称中删除前导“/”
[root@localhost /]# find /var/log/-iname anaconda.*-exec tar -cvf file.tar {} \; tar:从成员名称中删除前导“/” /var/log/anaconda.log tar:从成员名称中删除前导“/” /var/log/anaconda.xlog tar:从成员名称中删除前导“/” /var/log/anaconda.yum.log tar:从成员名称中删除前导“/” /var/log/anaconda.syslog tar:从成员名称中删除前导“/” /var/log/anaconda.program.log tar:从成员名称中删除前导“/” /var/log/anaconda.storage.log
简单来说,以下两者有何区别?
find var/log
和find /var/log
答案1
笔记:看@Iain 的回答寻找更有效的解决方案。
请注意,find
将调用以下-exec
操作每一个文件它发现了。
如果您tar -cvf file.tar {}
对每个文件find
输出都运行,这意味着您每次都会覆盖file.tar
,这也解释了为什么您最终只剩下一个包含最后anaconda.storage.log
一个文件find
输出的档案。
现在你真的想附加将文件放入存档中,而不是每次都创建它(这是该-c
选项的作用)。因此,请使用以下命令:
find var/log/ -iname "anaconda.*" -exec tar -rvf file.tar {} \;
该-r
选项将附加到档案中,而不是每次都重新创建它。
笔记:替换-iname anaconda.*
为-iname "anaconda.*"
。星号是通配符,可以扩展在 shellfind
看到它之前,它就已经被删除了。为了防止这种扩展,请将参数括在双引号中。
至于tar
删除前导/
:档案应该只包含相对的文件名。如果您添加以 开头的文件/
,则它们将存储为绝对/var/…
例如,文件名,其字面意思就是您的计算机上的文件名。
IIRC 这只是对 GNU 以外的实现的一种预防措施,这样更安全,因为如果档案包含相对文件名,则在提取档案tar
时不会覆盖实际数据。/var/…
答案2
您可以使用类似如下的方法:
find var/log -iname 'anaconda.*' -print0 | tar -cvf somefile.tar --null -T -
和-print0
一起-T
作用允许文件名带有空格、换行符等等。最后-
告诉 tar 从 stdin 读取输入文件名。
请注意,-print0
必须位于声明的末尾,这个答案。否则,您可能会获得比预期更多的文件。
答案3
尝试这个:
tar -cvf file.tar `find var/log/ -iname "anaconda.*"`
您尝试使用find
。-exec tar
但该选项的工作方式是-exec
,它会对找到的每个匹配文件运行一次该命令,从而导致tar
每次都覆盖它生成的 tar 文件。这就是为什么您只得到最后一个。此外,您需要将您指定的模式放在引号中,find
以便 shell 在将其传递给 之前不会对其进行扩展find
。
使用带有反引号的命令替换(或者$(...)
如果您愿意,可以使用符号),将生成的整个名称列表find
作为参数粘贴回命令行tar
,使其一次将它们全部写入。
答案4
有两种方法-exec
可以工作。一种方法是多次运行该命令 - 每个文件一次;另一种方法运行该命令一次,将所有文件作为参数列表。
-exec tar -cvf file.tar {} ';'
对每个文件运行tar
命令,每次都覆盖存档。-exec tar -cvf file.tar {} '+'
运行tar
一次命令,创建所有找到的文件的存档。