Рекурсивно обрабатывать zip-архивы для извлечения файлов, отказываясь от конкретного формата файлов

4842
Fr0zenFyr

ОБНОВЛЕНИЕ: Я заметил, что многие люди просматривают эту ветку, что заставляет меня поверить, что эта ситуация не так уж редка. Во всяком случае, я задал подобный / связанный вопрос о SO здесь, у которого также есть довольно приличные решения, которые могут решить проблему лучше.

На моем компьютере с Windows 7 у меня есть каталог, полный загруженных дампов в ZIP-архивах. Каждый архив содержит несколько текстовых файлов, PDF-файлов и редко XML-файлов. Я хочу извлечь все содержимое каждого ZIP-архива в соответствующую папку (должна быть создана во время процесса), исключая / игнорируя извлечение PDF-файлов. После извлечения необходимых файлов из архива обработанный zip-файл не должен быть удален (или я хотел бы знать, как я могу управлять им в различных ситуациях).

Если это помогает узнать, количество архивов в каталоге находится в диапазоне от 60 до 70 тыс. Кроме того, мне нужны отдельные выходные каталоги, потому что файлы в архиве могут иметь те же имена, что и файлы в других.

Например,

  • У меня есть все мои архивы, как one.zip, например, two.zipв, скажем,D:\data
  • Я создаю новую папку для обработанных данных, скажем, D:\extracted
  • Теперь данные из D:\data\one.zipдолжны перейти к D:\extracted\one. Здесь D:\extracted\oneдолжно быть создано автоматически.
  • Во время этого полного процесса распаковки не нужно извлекать все обнаруженные PDF-файлы (игнорировать). Нет смысла извлекать, а затем удалять.
  • (Необязательно) Файл журнала должен храниться, скажем, вD:\extracted. Идея состоит в том, чтобы использовать этот файл для возобновления обработки с того места, где он был оставлен в случае ошибки.
  • (Необязательно) Скрипт должен позволить мне решить, хочу ли я сохранить исходные архивы или удалить их после обработки.

Я уже провел поиск, чтобы найти решение, но не смог его найти. Я сталкивался с несколькими вопросами, подобными этим

  1. Рекурсивно разархивируйте файлы, где они находятся, затем удалите архивы
  2. 7 zip экстракт рекурсивно
  3. Можно ли рекурсивно перечислить содержимое файла zip с 7 zip без распаковки

но они не сильно помогли (кстати, я не профессионал в Windows). Я открыт для установки безопасного и бесплатного программного обеспечения сторонних производителей (с открытым исходным кодом), такого как 7-zip.

РЕДАКТИРОВАТЬ: Есть ли готовый инструмент, чтобы сделать то, что мне нужно, я уже пробовал Multi Unpacker . Он не создает новые каталоги, он не может игнорировать файлы * .pdf. Начать даже медленно, я думаю, что сначала он читает все архивы в источнике, а затем начинает их обрабатывать.

Заранее спасибо!

0
Я не вижу способа обойти это без пакетного сценария или сценария PowerShell, насколько я знаю, что не существует готового решения для чего-то подобного. private_meta 9 лет назад 0
@private_meta спасибо за ваш ответ. Я уже догадался об этом, но это хорошо, чтобы быть уверенным. Можете ли вы указать мне правильное направление для написания PowerShell для этого. Я также понимаю, что игнорирование PDF-файлов во время извлечения является огромной проблемой, поэтому я готов позволить сценарию извлечь все и затем удалить PDF-файлы. Fr0zenFyr 9 лет назад 0
связанные: http://superuser.com/q/321829/243637 Fr0zenFyr 7 лет назад 0

1 ответ на вопрос

1
private_meta

Изменяя найденный здесь ответ, этот фрагмент скрипта PowerShell должен делать то, что вы хотите. Просто сохраните его как файл с расширением ".ps1". При вызове, просто назовите его как ./filename.ps1, и он извлечет файлы в отдельные папки, удалит zip-файлы и удалит все файлы с расширением .pdf. Я не проверял, правильно ли он работает с рекурсивными путями, но стоит проверить его.

Изменить: Если вы не хотите, чтобы ваши zip-файлы были удалены, удалите или закомментируйте (#) строкуrmdir -Path $_.FullName -Force

Требования: PowerShell, 7-Zip и для вас, чтобы установить 7-Zip путь в файле.

param([string]$folderPath="D:\Blah\files")  Get-ChildItem $folderPath -recurse | %{   if($_.Name -match "^*.`.zip$") { $parent="$(Split-Path $_.FullName -Parent)";  write-host "Extracting $($_.FullName) to $parent"  $arguments=@("e", "`"$($_.FullName)`"", "-o`"$($parent)\$($_.BaseName)`""); $ex = start-process -FilePath "`"C:\Program Files\7-Zip\7z.exe`"" -ArgumentList $arguments -wait -PassThru;  if( $ex.ExitCode -eq 0) { write-host "Extraction successful, deleting $($_.FullName)" rmdir -Path $_.FullName -Force $arguments1="$($parent)\$($_.BaseName)\*.pdf" rmdir -Recurse -Path $arguments1 } } } 
Я хотел попросить вас помочь мне изменить код из того же ответа, вы читатель разума. Я попробую этот код и сообщу о прогрессе здесь. Я очень рад, что вы уделили время, чтобы внимательно прочитать мой вопрос и охватить почти все его аспекты. Fr0zenFyr 9 лет назад 0
Вы можете использовать его как основу и изменять по мере необходимости. Часть о том, как не извлекать PDF-файлы, в первую очередь является серьезной проблемой, я не думаю, что она будет работать с обычными инструментами. private_meta 9 лет назад 0
Кроме того, если вы используете более одного «param», вам нужно вызывать их так: «./script.ps -folderPath path -delete» и так далее. Информацию о переключателях см. В [этом] (http://www.powershellmagazine.com/2013/12/20/using-powershell-switch-vs-boolean-parameters-in-sma-runbooks/) private_meta 9 лет назад 0
Спасибо друг, я снимаю тебе шляпу. Этот скрипт достиг почти всего, что я хотел (кроме файла журнала). Поскольку не было лучшего ответа, чем этот, я принимаю ваш ответ в качестве решения. Ох, и кстати, по умолчанию PowerShell моей системы не позволяет мне запускать скрипт, говоря, что он отключен. У меня было два варианта: либо подписать скрипт, либо выполнить `set-ExecutionPolicy Unrestricted` в PowerShell от имени администратора. Я попробовал оба варианта, и они сработали, хотя 1-й вариант лучше, но это выходит за рамки этого комментария, чтобы объяснить почему. Fr0zenFyr 9 лет назад 0
Привет еще раз, сценарий работал прекрасно, за исключением одного случая, который я узнал. Немногие из моих zip-файлов имели подпапки, скрипт извлекал папку и помещал ее содержимое параллельно ей (вне подкаталога). Можно ли это как-то исправить? Кроме того, у меня было несколько файлов, которые были `.tar` и` .zip` внутри них, так что я должен заменить `if ($ _. Name -match" ^ *. '. Zip $ ")` на их рекурсивную обработку ? Заранее спасибо. Fr0zenFyr 9 лет назад 0
Если вы замените `$ arguments = @ (" e ",` на `$ arguments = @ (" x ",` это должно сохранить структуру каталогов, пожалуйста, проверьте это. Что касается рекурсивного извлечения, я не знаю, работает ли он как это, но вы можете сделать так, чтобы скрипт сам вызывал новый каталог, в данном случае каждый подкаталог. Если в корневом каталоге папки есть zip-файл, он будет распакован, в противном случае он получит много более сложный. Я не достаточно хорош с PowerShell, хотя. private_meta 9 лет назад 1
Я начал не любить Power Shell сейчас, это кажется запутанным и сложным. Я пытаюсь справиться с этим с помощью пакетного сценария, я уже сделал большую часть всего за 1 строку. Спасибо, приятель за ответ, хотя. Я только что опубликовал [вопрос по SO] (http://stackoverflow.com/q/24339419/1369473), вы можете увидеть мой прогресс там. Fr0zenFyr 9 лет назад 0