如何在混乱的文件夹中解压缩、解焦油 -xvf -- 解压缩?

如何在混乱的文件夹中解压缩、解焦油 -xvf -- 解压缩?

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

有一些取消存档的方法,还有其他方法吗?

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

  2. 如果提取的文件量较少,逐一提取,速度慢、繁琐且容易出错。

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

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

答案1

按名字

您可以生成存档中的文件列表并删除它们,尽管这对于 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

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

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

使用保险丝

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

您可以使用保险丝拉链查看 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

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

按日期

假设除了您的提取之外,同一层次结构中没有其他任何活动,您可以通过最近的文件来判断提取的文件时间。如果您刚刚创建或移动了 zip 文件,则可以将其用作截止;否则用于ls -lctr确定合适的截止时间。如果您想确保不删除拉链,则没有理由进行任何手动批准:find完全有能力排除它们。以下是使用 zsh 或find;的示例命令请注意,-cmin-cnewer初级不在 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

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

touch -d … cutoff
find . -type f -newercm cutoff -delete

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

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

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

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

警告,我尚未测试此答案中的大部分命令。在删除之前始终检查文件列表(echo先运行,然后rm再运行)。

答案2

我感觉很愚蠢,无论如何,当我遇到类似的问题时,我挠头写了这个脚本。我使用cpio标志-it来获取文件列表;您可以对其他归档器使用等效命令。棘手的部分是,cpio 存档来自 initrd,我提取到 中/,因此许多文件夹和文件与工作系统中的名称相同。幸运的是 cpio 没有覆盖我现有的任何文件。我使用时间检查来确保不会删除错误命令之前存在的任何内容。

#! /bin/sh

files=$(cpio -it < /mnt/temp/lglive.cpio)

for i in ${files}
do
    name=$(stat -c "%n" ${i})
    time=$(stat -c "%Y" ${i})
    # Time of the creation of the mess: 1296457595
    if [[ ${time} -gt 1296457590 && ${time} -lt 1296457600 ]]
    then
        if [[ -f ${name} ]]
        # If it is a file, it must have been created as part of the mess.
        then
            echo "rm ${name}"
        elif [[ -d ${name} ]]
        # If it is a directory, it may have been part of the mess
        # or maybe some files underneath it is created as part of the mess.
        then
            if [[ $(ls -A ${name}) ]]
            # If the directory contains something then don't delete it.
            then
                echo "${name} is not empty"
            # If the directory is empty then assume it is rubbish.
            else
                echo "rmdir ${name}"
            fi
        fi
    fi
done

echo "Files and directories still exist after the removal:"
for i in ${files}
do
    if [[ -e ${i} ]]
    then
        echo ${i}
    fi
done

答案3

将存档中的文件列表提供给 怎么样xargs rm

那将是tar -tf tarbomb.tar | xargs rmunzip --list zipbomb.zip | xargs rm

答案4

我在 zsh 中使用以下函数:

ununzip () {
    rm -r $(unzip -l $1 | grep -v 'Archive:' | \
    grep '[/.]' | sed 's![^a-zA-Z]([a-zA-Z./])!\1!')
}

即命令替换以删除已清理的输出中的所有文件unzip -l

tar tvf可以以类似的方式使用。

相关内容