Декомпресія відразу декількох файлів


27

У мене .zipв одній папці більше 200 файлів. Я не хочу розпаковувати їх по черзі. Я хочу витягти тих, хто використовує одну команду або сценарій. Як це зробити.

Відповіді:


38

Якщо ви дійсно хочете паралельно розтискати їх, ви можете зробити це

for i in *zip; do unzip "$i" & done

Це, однак, запустить N процесів для файлів N .zip і може бути дуже важким у вашій системі. Для більш контрольованого підходу, запускаючи лише 10 паралельних процесів одночасно, спробуйте це:

find . -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

Щоб контролювати кількість запущених паралельних процесів, перейдіть -Pдо того, що вам потрібно. Якщо ви не хочете повторно вводити підкаталоги, зробіть це замість цього:

find . -maxdepth 1 -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

Крім того, ви можете встановити GNU паралельно, як запропонував @OleTange в коментарях, і запустіть

parallel unzip ::: *zip

3
Паралельно працювати паралельно - це приємна ідея, але чи не буде диск вводу / виводу основним вузьким місцем?
Падді Ландау

1
@PaddyLandau не впевнений, мені доведеться перевірити. Це залежатиме від швидкості алгоритму декомпресії проти швидкості диска, який я уявляю.
тердон

Використовуйте -execабо -execdirзамість трубопроводів до xargs. Це не тільки простіше зрозуміти, але також і менш схильне до помилок і використовує менше системних ресурсів. find . -name '*.zip' -exec unzip {} ';'(Ви повинні цитувати напівколонку.)
Падді Ландау

@PaddyLandau, єдина причина, по якій я звертаюся до xargs, - це запускати паралельно, як запитала ОП. -exec \;(ви можете уникнути крапки з комою, не потребуючи лапок), виконуватимете кожну команду послідовно. -exec +краще, але це не працюватиме тут, оскільки це не так unzipпрацює.
тердон

Я думаю, що ми по-різному зрозуміли ОП. Ви читаєте його так, як хочете його паралельно, тоді як я розумів, що він означає одну команду замість кількох команд. Ну, у нього зараз є обидва методи :)
Падді Ландау

17

GNU паралельно команда добре підходить для такого роду речі. Після:

$ sudo apt-get install parallel

Потім

ls *.zip | parallel unzip

Це використовуватиме стільки ядер, скільки у вас є, зберігаючи кожне ядро ​​зайнятим розкручуванням, поки вони не будуть виконані.


Це краще використовувати echo *.zipзамість цього, щоб запобігти проникненню додаткової інформації. Однак це питання є тим же, що і у відповіді @ Гуру, воно порушує імена файлів, що містять пробіли.
nyuszika7h

1
@ nyuszika7h На відміну від xargsGNU Паралель не розбивається на імена файлів, що містять пробіл / вкладку / цитату. Тільки якщо назви файлів містять нові рядки, вам доведеться бути обережними. Наприклад, використовуючи:parallel unzip ::: *.zip
Оле Танге

@ nyuszika7h - Це вагомі причини, щоб уникнути як стандартних команд, так і розміщення пробілів у назви файлів.
Уейн Конрад

@ nyuszika7h використовувати так echoсамо погано, як і використовувати ls. Глобінг і цикл на час є найбезпечнішим.
тердон

1
@NateEldredge Хоча цей шанс був більшим ще в часи, коли в системах був лише один магнітний диск, в наші дні з RAID-кодами з декількома шпинделями та флеш-дисками цей шанс менший. Найкраще робити, звичайно, виміряти і подивитися, як поводиться ваша система. Нещодавно я використовував 40 шпиндельних RAID, де оптимальний паралелізм для голодних процесів вводу / виводу становив 10: Це не дало 10-кратної швидкості - лише 6x, але менше 10 процесів дало менше 6x.
Оле Танге

12

Можна використовувати таку команду:

Перша зміна каталогу в терміналі до каталогу, який містить .zip файли:

cd /path

Потім виконайте цю команду, щоб розпакувати всі .zip файли:

for z in *.zip; do unzip "$z"; done

10

Якщо .zipу вашій папці багато файлів, і ви хочете розпакувати їх, відкрийте термінал і перейдіть до своєї папки за допомогою:

cd <path_to_folder>

Тепер використовуйте цю команду, щоб розпакувати весь .zipфайл:

ls *.zip | xargs -n1 unzip

3
Це не вдасться, якщо будь-яке з назв файлів містить пробіл.
тердон

1
так, ви праві.
g_p

Це краще використовувати echo *.zipзамість цього, щоб запобігти lsпроникненню додаткової інформації про псевдонім, але це все ще не вирішує проблему з пробілами.
nyuszika7h

1
@OleTange Якщо ви цього не помітили, я сказав, що він все ще не відповідає іменам файлів з пробілом у них.
nyuszika7h

1
Ніколи не залежати від результатів lsсценаріїв, оскільки його вихід недостатньо визначений між версіями. Замість цього подивіться на відповідь від @terdon, оскільки вона вирішує всі проблеми цього рішення.
Падді Ландау

6

Ви можете використовувати Find з -execподібним чином,

find . -name "*.zip" -exec unzip {} \;

Це буде працювати , якщо файл має місце в назві.


3

Нетермінальний метод.

Просто виберіть поштові файли, клацніть правою кнопкою миші на одному і виберіть extract here. Ви можете одночасно вибрати всі або лише декілька поштових файлів.


1

unzip \*.zip або unzip '*.zip'

Очевидне unzip *.zipне працює, тому що оболонка розширює його unzip foo.zip bar.zip ...і unzipінтерпретує перше ім'я файлу як zip-файл, а наступні імена файлів як файли, які слід витягнути з цього поштового файлу.

Однак unzipсеред команд Unix трохи незвично тим, що він робить власні глобальні розширення. Якщо *оболонка не розгорнута, unzip зробить це, а всі отримані імена файлів буде сприйнято як поштові файли для обробки. Тож у цьому спеціальному випадку можна піти без forпетлі xargsтощо.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.