Извлечение вложенных zip-файлов

Если Вы только ищете одну возможность и хотите остаться главным образом в оболочке вместо использования awk или perl, Вы могли сделать что-то как:

tail -F /path/to/serverLog | 
grep --line-buffered 'server is up' | 
while read ; do my_command ; done

... который будет работать my_command каждый раз "сервер закончился", появляется в файле журнала. Для нескольких возможностей Вы могли, возможно, отбросить grep и вместо этого используйте a case в while.

Капитал -F говорит tail наблюдать за файлом журнала, который будет повернут; т.е. если текущий файл переименован, и другой файл с тем же именем занимает свое место, tail переключится на новый файл.

--line-buffered опция говорит grep сбросить его буфер после каждой строки; иначе, my_command может не быть достигнут своевременно (предполагающий, что журналы обоснованно измерили строки).

15
10.04.2017, 22:26
9 ответов

Это извлечет все zip-файлы в текущий каталог, исключая любой zipfiles, содержавший в них.

find . -type f -name '*.zip' -exec unzip -- '{}' -x '*.zip' \;

Хотя это извлекает содержание к текущему каталогу, не, все файлы закончатся строго в этом каталоге, так как содержание может включать подкаталоги.

Если Вы на самом деле хотели все файлы строго в текущем каталоге, можно работать

find . -type f -mindepth 2 -exec mv -- '{}' . \;

Примечание: это ударит файлы, если будет два с тем же именем в различных каталогах.

Если Вы хотите рекурсивно извлечь все zip-файлы и zip, содержавшие в, следующие извлечения все zip-файлы в текущем каталоге и все zip, содержавшие в них к текущему каталогу.

while [ "`find . -type f -name '*.zip' | wc -l`" -gt 0 ]
do
    find . -type f -name "*.zip" -exec unzip -- '{}' \; -exec rm -- '{}' \;
done
13
27.01.2020, 19:50
  • 1
    этот цикл с условием продолжения помог мне много на этическом соревновании по взламыванию, где они подготовили вложенный zip-файл, идущий 31 337 уровней глубоко, Спасибо! –  peedee 10.12.2015, 11:17
  • 2
    Вам мог бы понравиться этот вариант, который я использую для рекурсивного извлечения содержания из вложенного уха, войны, файлов банки: Существенное различие gist.github.com/tyrcho/479c18795d997c201e53 - это, создает вложенную папку для каждого архива. while [ "найти. - тип f - называют '*.? площадь' | туалет-l" -gt 0 ]; do find -type f -name "*.?ar" -exec mkdir -p '{}.dir' \; -exec unzip -d '{}.dir' -- '../{}' \; -exec rm -- '{}' \;; done –  Michel Daviot 21.01.2016, 19:17

Насколько я понимаю, у Вас есть архивы zip, которые сами содержат архивы zip, и требуется разархивировать вложенные zip каждый раз, когда каждый извлечен.

Вот является удар 4 сценариями, которые разархивировали все zip в текущем каталоге и его подкаталогах рекурсивно, удаляет каждый zip-файл после того, как он был разархивирован и продолжает идти, пока существуют zip-файлы. Zip-файл в подкаталоге извлечен относительно того подкаталога. Предупреждение: непротестированный, сделайте резервное копирование исходных файлов перед испытанием его или заменой rm путем перемещения zip-файла вне дерева каталогов.

shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ] do
  for z; do
    ( cd -- "$(dirname "$z")" &&
      z=${z##*/} &&
      unzip -- "$z" &&
      rm -- "$z"
    )
  done
done

Сценарий будет также работать в zsh, если Вы замените shopt строка с setopt nullglob.

Вот портативный эквивалент. Условие завершения является немного сложным потому что find спонтанно не возвращает состояние, чтобы указать, нашло ли оно какие-либо файлы. Предупреждение: как выше.

while [ -n "$(find . -type f -name '*.zip' -exec sh -c '
    cd "${z%/*}" &&
    z=${z##*/} &&
    unzip -- "$z" 1>&2 &&
    rm -- "$z" &&
    echo 1
')" ]; do :; done
4
27.01.2020, 19:50

unzip не делает этого, потому что UNIX путь должен сделать одну вещь и сделать это хорошо, не обработать все сумасшедшие особые случаи в каждом инструменте. Таким образом необходимо использовать оболочку (который делает задание "сходящихся вещей" хорошо). Это делает это вопросом о программировании, и так как на ВСЕ возможные вопросы программирования ответили на StackOverflow, здесь: Как Вы рекурсивно разархивировали архивы в каталоге и его подкаталогах от командной строки Unix?

1
27.01.2020, 19:50
  • 1
    я определенно не назвал бы "использование оболочки" вопросом о программировании, и "сценариями оболочки", перечислен в FAQ как на теме –  Michael Mrozek♦ 27.11.2010, 20:02
  • 2
    , я не означал подразумевать, что это было вне темы здесь вообще, я просто хотел выровнять по ширине, почему это на теме в StackOverflow. –  Thomas Themel 29.11.2010, 09:43

Самый легкий путь состоит в том, чтобы использовать atool: http://www.nongnu.org/atool/ Это - очень хороший сценарий, которые используют zip, разархивировали, смолят, rar и т.д. программы для извлечения любого архива.

Использовать atool -x package_name.zip разархивировать их всех или если Вы хотите использовать его в каталоге со многим простым использованием zip-файлов for цикл:

for f in *; do atool -x $f; fi (Вы будете иметь к cd в желаемый каталог с zip-файлами перед использованием этого).

1
27.01.2020, 19:50
  • 1
    atoolповедение здесь значительно не отличается от, разархивировали, я сказал бы, оно рекурсивно не извлекает zip-файлы также. –  Thomas Themel 29.11.2010, 09:50
  • 2
    @Thomas Themel: действительно ли Вы уверены, что это рекурсивно не извлекает zip-файлы? Это может извлечь из deb файлов tar.gz рекурсивно, но у меня нет времени банкомат для тестирования его с вложенными архивами zip:\ –   02.12.2010, 00:58

Вы захотите быть тщательными автоматически разархивировавшими zip-файлами в zip-файлах:

http://research.swtch.com/2010/03/zip-files-all-way-down.html

Возможно придумать zip-файл, который производит zip-файл, как произведено, который производит zip-файл, как произведено, и т.д. и т.д. и т.д. Таким образом, можно сделать zip-файл, из которого это является фиксированным oint, "разархивировали" программу.

Кроме того, я, кажется, вспоминаю людей, делающих zip-файлы, которые "взорвались" бы, который является очень маленьким zip-файлом, разархивировал бы к мультигигабайтам вывода. Это - фасет метода сжатия.

0
27.01.2020, 19:50

Этот сценарий жемчуга извлечет каждый .zip файл в свой собственный подкаталог. Запустите скрипт несколько раз для обработки вложенных zip-файлов. Это не удаляет .zip файлы после извлечения, но Вы могли внести то изменение путем добавления удаления связь () вызов.

#!/usr/bin/perl -w

# This script unzips all .zip files it finds in the current directory
# and all subdirectories.  Contents are extracted into a subdirectory
# named after the zip file (eg. a.zip is extracted into a/).
# Run the script multiple times until all nested zip files are
# extracted.  This is public domain software.

use strict;
use Cwd;

sub process_zip {
    my $file = shift || die;
    (my $dir = $file) =~ s,/[^/]+$,,;
    (my $bare_file = $file);
    $bare_file =~ s,.*/,,;
    my $file_nopath = $bare_file;
    $bare_file =~ s,\.zip$,,;
    my $old_dir = getcwd();
    chdir($dir) or die "Could not chdir from '$old_dir' to '$dir': $!";
    if (-d $bare_file) {
        chdir($old_dir);
        # assume zip already extracted
        return;
    }
    mkdir($bare_file);
    chdir($bare_file);
    system("unzip '../$file_nopath'");
    chdir($old_dir);
}

my $cmd = "find . -name '*.zip'";
open(my $fh, "$cmd |") or die "Error running '$cmd': $!";
while(<$fh>) {
    chomp;
    process_zip($_);
}
1
27.01.2020, 19:50

Может быть, это поможет (у меня сработало):

function unzipAll(){

# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`

# while archives exists do extract loop
while [ "$archLstSize" -gt 0 ]; do

# extract and remove all archives (found on single iteration)
for x in $archLst; do 
mv "${x}" "${x}_";
unzip "${x}_" -d "${x}" && rm "${x}_"; 
done; #EO for

# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`

done #EO while

}
0
27.01.2020, 19:50

Мне нужно было решение, подобное предложенному Джайлсом в 2010 году, за исключением того, что мне нужно было сохранить структуру папок, а не распаковывать все в каталог верхнего уровня. Вот мой взгляд на него с добавлением/изменением трех строк:

#!/bin/bash
shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ]
do
    for z
    do
        ( cd -- "$(dirname "$z")" &&
            z=${z##*/} &&
            cp -- "$z" "$z".bak &&
            mkdir -- "$z"dir &&
            unzip -- "$z" -d "$z"dir &&
            rm -- "$z"
        )
    done
done
0
27.01.2020, 19:50

Проверьте эту утилиту на основе Java nzip для вложенных zip-файлов. Извлечение и сжатие вложенных zip-файлов можно легко выполнить с помощью следующих команд

java -jar nzip.jar -c list -s readme.zip

java -jar nzip.jar -c extract -s "C :\project\readme.zip" -t readme

java -jar nzip.jar -c compress -s readme -t "C :\project\readme.zip"

ПС. Я автор и буду рад быстро исправить любые ошибки.

0
27.01.2020, 19:50

Теги

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