Как к de-unzip, de-tar-xvf — de-unarchive в грязной папке?

циклическое устройство является псевдо ("поддельным") устройством (на самом деле просто файл), который действует как основанное на блоке устройство. Вы хотите смонтировать файл (disk1.iso), который будет действовать как вся файловая система, таким образом, Вы будете использовать цикл.

-o прибывает из - опции.

И последняя вещь, если Вы хотите искать "-o", необходимо выйти из '-'. Попробуйте:

man mount | grep "\-o"
14
18.03.2019, 04:09
6 ответов

По имени

Можно генерировать список файлов в архиве и удалить их, хотя это раздражающе трудно с archivers те, которые разархивировали или 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

Использование 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

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

По дате

Принятие там не было другим никаким действием в той же иерархии, чем Ваше извлечение, можно сказать извлеченные файлы их недавним ctime. Если Вы просто создали или переместили zip-файл, можно использовать его в качестве сокращения; иначе используйте ls -lctr определить подходящее время сокращения. Если Вы хотите удостовериться, что не удалили zip, нет никакой причины сделать любое ручное одобрение: find совершенно способно к исключению их. Вот команды в качестве примера с помощью zsh или find; обратите внимание что -cmin и -cnewer основные устройства не находятся в POSIX, но существуют на Linux (и другие системы с GNU находят), *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 находят, 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 если это в порядке).

11
27.01.2020, 19:51
  • 1
    я наконец сталкиваюсь с этой проблемой сегодня. Как корень! В конце я использовал комбинацию "По имени" и "По дате" –  phunehehe 31.01.2011, 10:58

Я чувствую себя глупым, так или иначе я поцарапал голову для описывания этого сценария, когда у меня была подобная проблема. Я использовал cpio с -it флаг для получения списка файлов; можно использовать эквивалентные команды для другого archivers. Хитрая часть, архив 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
1
27.01.2020, 19:51

Как насчет того, чтобы подать список файлов в архиве к xargs rm?

Это было бы tar -tf tarbomb.tar | xargs rm или unzip --list zipbomb.zip | xargs rm.

0
27.01.2020, 19:51
  • 1
    Команды, как дали не будут работать в общем случае, и это опасно, так как Вы удаляете файлы. xargs ожидает его вход, заключенный в кавычки специфическим способом который find не производит. Использовать xargs -I rm {} так, чтобы xargs обработал один объект на строку вместо этого. Для разархивировать команды, какую реализацию Вы имеете? Мой (Debian/Ubuntu) не имеет --list, только -l, и это только печатает имена файлов, так, чтобы дополнительная обработка была необходима. –  Gilles 'SO- stop being evil' 24.12.2010, 15:53
  • 2
    @Gilles: 1) да, это опасно, но так как мы, по-видимому, перезаписали исходные файлы - их уже не стало. 2) я не говорил о find. 3) Вы корректны о unzip, Я не протестировал и там, казалось, не был никакой опцией для неукрашенного списка. Нет --list на моей Ubuntu также - я просто не протестировал. –  alex 24.12.2010, 20:52
  • 3
    Извините за консервированный ответ, замену tar -t для find. Но мои другие точки стоят. Существует реальный риск, что Ваша команда, как дали удалила бы несвязанный файл. –  Gilles 'SO- stop being evil' 26.12.2010, 12:53
  • 4
    tar -tf tarbomb.tar распечатает имена файлов один на строку, таким образом, Вы могли сделать tar -tf tarbomb.tar | while IFS=$'\n' read -r filename; do rm "$filename"; done или подобный. –  Mikel 25.01.2011, 00:44

Едва ли, как насчет чего Вы попросили, но использовать, "разархивировали весь" сценарий вместо.

unzip *.zip

Тем путем вывод из каждого файла входит в свой собственный каталог.

#!/bin/bash
for f in *.zip ; do unzip -n "$f" -d "${f/%zip/out}"; done
0
27.01.2020, 19:51

Я использую следующую функцию в zsh:

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

Т.е. замена команды для удаления всех файлов в очищенном выводе unzip -l.

tar tvf мог использоваться похожим способом.

0
27.01.2020, 19:51

Недавно у A была проблема с распаковкой, команда --listничего не сделала в Ubuntu/Kali (Zip 3.0 (5 июля 2008 г. ), Info -ZIP ), а -l] экспортирует в бесполезный удобочитаемый формат. Так что я счастливо закончил с примером на основе tar -xargs -:

zipinfo -1./archive.zip | xargs rm -rf

0
16.11.2021, 08:22

Теги

Похожие вопросы