【发布时间】:2011-10-01 10:22:06
【问题描述】:
我将一些东西解压到一个已经包含很多东西的目录中。我想解压到一个单独的目录中。现在有太多文件无法区分。但是,我解压的文件刚刚创建(对吗?),并且原始文件很久没有修改(至少一天)。有没有办法根据它们的创建信息只删除这些未解压缩的文件?
【问题讨论】:
我将一些东西解压到一个已经包含很多东西的目录中。我想解压到一个单独的目录中。现在有太多文件无法区分。但是,我解压的文件刚刚创建(对吗?),并且原始文件很久没有修改(至少一天)。有没有办法根据它们的创建信息只删除这些未解压缩的文件?
【问题讨论】:
Tar 通常会恢复文件时间戳,因此按时间过滤不太可能起作用。
如果你还有 tar 文件,你可以用它来删除你解压后的内容:
tar tf file.tar --quoting-style=shell-always |xargs rm -i
上述方法在大多数情况下都有效,但并非全部(文件名中有回车符会破坏它),所以要小心。
您可以通过添加-r 来删除目录,但手动删除顶级目录可能更安全。
【讨论】:
rm 之后应该有一个-r。由于 Mat 没有更新答案,我将自己添加。
-r只会增加意外字符造成的伤害。除非该存档中有数百个顶级目录,否则我会手动处理它们。
-r 确实有意义。但我在回答中解决了另一个问题,实际上并没有那么复杂。
找到 . -mtime -1 -类型 f | xargs rm
但要先测试
找到 . -mtime -1 -类型 f | xargs 回显
【讨论】:
-print0 和xargs -0。您不希望文件名中的随机空格字符给您带来问题。其次,tar 恢复时间戳,所以这里实际上不能使用 mtime。也许有时,也许,如果你的文件系统已经被配置为更新它。
这个问题有几个不同的答案,按照复杂度递增的顺序排列。
首先,如果这是一次性的,在这个特定的例子中,你绝对确定你的文件名中没有奇怪的字符(空格是可以的,但不是制表符、换行符或其他控制字符,也不是 unicode 字符)这个将工作:
tar -tf file.tar | egrep '^(\./)?[^/]+(/)?$' | egrep -v '^\./$' | tr '\n' '\0' | xargs -0 rm -r
所有的 egrepping 都是跳过子目录的所有子目录。
另一种适用于时髦文件名的方法是:
mkdir foodir
cd foodir
tar -xf ../file.tar
for file in *; do rm -rf ../"$file"; done
这将创建一个目录,您的存档已在其中展开,但听起来您似乎已经想要了。它也不会处理任何名称以.开头的文件。
要使该方法适用于以. 开头的文件,请执行以下操作:
mkdir foodir
cd foodir
tar -xf ../file.tar
find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 sh -c 'for file in "$@"; do rm -rf ../"$file"; done' junk
最后,从Mat's answer 获取,您可以这样做,它适用于任何文件名,并且不需要您再次解压缩目录:
tar -tf file.tar | egrep '^(\./)?[^/]+(/)?$' | grep -v '^\./$' | tr '\n' '\0' | xargs -0 bash -c 'for fname in "$@"; do fname="$(echo -ne "$fname")"; echo -n "$fname"; echo -ne "\0"; done' junk | xargs -0 rm -r
【讨论】:
您可以一次性处理文件和目录:
tar -tf ../test/bob.tar --quoting-style=shell-always | sed -e "s/^\(.*\/\)'$/rmdir \1'/; t; s/^\(.*\)$/rm \1/;" | sort | bash
你可以看到会发生什么离开管道到 'bash'
tar -tf ../test/bob.tar --quoting-style=shell-always | sed -e "s/^\(.*\/\)'$/rmdir \1'/; t; s/^\(.*\)$/rm \1/;" | sort
要处理带有换行符的文件名,您需要更多处理。
【讨论】: