如何在凌乱的文件夹中解压、解压 -xvf -- 解压?

15 tar zip archive file-management

通常,我取消归档内容,$ mkdir newFolder; $ mv *.zip newFolder; $ cd newFolder; $unzip *.zip但有时我会变得懒惰,只是在任意文件夹中进行操作,$ unzip *.zip因此不时会弄乱其他内容。我将在这里列出一些方法——一些存档版本肯定有蹩脚的标志,而另一些则更加简陋,我对后者更感兴趣。

有些方法可以取消存档,还有其他方法吗?

  1. $ find . -anewer fileThatExistedBeforeUnarchieving -ok rm '{}' \;缺点是它列出了*.zip目录,因此您需要使用 slow -ok、 slow 与许多*.zip匹配项,并且由于某种原因,它似乎并不匹配提取的所有内容。

  2. 如果提取的文件量少,一个一个,慢,麻烦,容易出错。

  3. 当我想确定存档的内容是否实际上是一个文件夹时,我有时会使用$ unzip -l *.bsd,至少在 obsd 的解压缩版本中工作。

如果您指的是某些存档工具,请在适当的时候说明它们。保持简单——我更感兴趣的是你如何做到这一点,而不是一个单一的工具。

Gil*_*il' 11

按名字

您可以在存档中生成文件列表并删除它们,尽管这对于诸如 unzip 或 7z 之类的存档程序来说很烦人,因为它们没有选项来生成一个简单的文件名列表。即使使用 tar,这也假设文件名中没有换行符。

tar tf foo.tar | while read -r file; do rm -- "$file" done
unzip -l foo.zip | awk '
    p && /^ --/ {p=2}
    p==1 {print substr($0, 29)}
    /^ --/ {++p}
' | while …
unzip -l foo.zip | tail -n +4 | head -n -2 | while …  # GNU coreutils only
7z l -slt foo.zip | sed -n 's/^Path = //p' | while …  # works on tar.*, zip, 7z and more
Run Code Online (Sandbox Code Playgroud)

您可以将它们移动到预期的目的地,而不是删除文件。

tar tf foo.tar | while read -r file; do
  if [ -d "$file" ]; then continue; fi
  mkdir -p "/intended/destination/${file%/*}"
  mv -- "$file" "/intended/destination/$file"
done
Run Code Online (Sandbox Code Playgroud)

使用保险丝

您可以(在大多数 unice 上)使用FUSE使用普通文件系统命令来操作存档,而不是依赖于外部工具。

您可以使用Fuse-zip来查看 zip 文件,使用 提取它cp,使用 列出其内容find等。

mkdir /tmp/foo.d
fuse-zip foo.zip /tmp/foo.d
## Remove the files that were extracted mistakenly (GNU/BSD find)
(cd /tmp/foo.d && find . \! -type d -print0) | xargs -0 rm
## Remove the files that were extracted mistakenly (zsh)
rm /tmp/foo.d/**(:"s~/tmp/foo.d/~~"^/)
## Extract the contents where you really want them
cp -Rp /tmp/foo.d /intended/destination
fusermount -u foo.d
rmdir foo.d
Run Code Online (Sandbox Code Playgroud)

AVFS创建整个目录层次结构的视图,其中所有档案都有一个关联目录(同名,末尾附加 #),似乎保存档案内容。

mountavfs
## Remove the files that were extracted mistakenly (GNU/BSD find)
(cd ~/.avfs/"$PWD/foo.zip#" && find . \! -type d -print0) | xargs -0 rm
## Remove the files that were extracted mistakenly (zsh)
rm ~/.avfs/$PWD/foo.zip\#/**/*(:"s~$HOME/.avfs/$PWD/foo.zip#~~"^/)
## Extract the contents where you really want them
cp -Rp ~/.avfs/"$PWD/foo.zip#" /intended/destination
umountavfs
Run Code Online (Sandbox Code Playgroud)

按日期

假设在同一层次结构中没有其他任何活动而不是您的提取,您可以通过最近的ctime告诉提取的文件。如果您刚刚创建或移动了 zip 文件,您可以将其用作截断;否则用于ls -lctr确定合适的截止时间。如果您想确保不移除拉链,则没有理由进行任何手动批准:find完全有能力排除它们。以下是使用 zsh 或find; 的示例命令。请注意,-cmin-cnewerprimaries 不在 POSIX 中,而是存在于 Linux(以及其他带有 GNU find 的系统)、*BSD 和 OSX 中。

find . \! -name '*.zip' -type f -cmin -5 -exec rm {} +  # extracted <5 min ago
rm **/*~*.zip(.cm-6)  # zsh, extracted ?5 min ago
find . -type f -cnewer foo.zip -exec rm {} +  # created or moved after foo.zip
Run Code Online (Sandbox Code Playgroud)

对于 GNU find、FreeBSD 和 OSX,另一种指定截止时间的方法是创建一个文件并使用touch将其 mtime 设置为截止时间。

touch -d … cutoff
find . -type f -newercm cutoff -delete
Run Code Online (Sandbox Code Playgroud)

您可以将它们移动到预期的目的地,而不是删除文件。这是 GNU/*BSD/OSX find 的一种方法,根据需要在目标中创建目录。

find . \! -name . -cmin -5 -type f -exec sh -c '
    for x; do
      mkdir -p "$0/${x%/*}"
      mv "$x" "$0/$x"
    done
  ' /intended/destination {} +
Run Code Online (Sandbox Code Playgroud)

Zsh 等效(几乎:这个复制整个目录层次结构,而不仅仅是包含文件的目录):

autoload zmv
mkdir -p ./**/*(/cm-3:s"|.|/intended/destination|")
zmv -Q '(**/)(*)(.cm-3)' /intended/destination/'$1$2'
Run Code Online (Sandbox Code Playgroud)

警告,我尚未测试此答案中的大部分命令。在删除之前总是查看文件列表(echo先运行,然后rm如果可以的话)。