Як змайструвати декілька файлів у командному рядку?


16

Пробачте це найосновніше запитання, але я не зміг знайти прямої відповіді чи простого прикладу обміну стеками.

Скажімо, у мене є папка файлів, яку я хотів би стиснути в один поштовий файл, яким я можу поділитися з моїми жахливими друзями з Windows (інакше я б просто використовував tarі робив це з ним). Це виглядає приблизно так:

.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
└── test.jpg

Якщо я zipвстановив:

sudo apt-get install zip

Я бачу, man zipщо це дозволяє мені використовувати список файлів:

- @ списки файлів. Якщо список файлів вказаний як - @ [Not on MacOS], zip приймає список вхідних файлів зі стандартного вводу замість командного рядка. Наприклад,

          zip -@ foo

Тому я створив, zip.lstщо виглядає приблизно так:

cat zip.lst

file1.txt
file2.txt
file3.txt
file.jpg
test.jpg

А тепер я спробував:

zip -@ zip.lst

Але це не зробило нічого, крім створення порожнього рядка на консолі. І я можу продовжувати натискати, Enterі це просто продовжує робити більше порожніх рядків, не здаючись виконувати команду. Після деякого пошуку я зрозумів, що мені потрібно припинити введення, натиснувши Ctrl+D

Але тепер я отримую цю помилку:

    zip warning: missing end signature--probably not a zip file (did you
    zip warning: remember to use binary mode when you transferred it?)
    zip warning: (if you are trying to read a damaged archive try -F)

zip error: Zip file structure invalid (zip.lst)

Що!? Як мій простий список не є "дійсною структурою файлів"? Поверніться до посібника для отримання додаткової інформації, і я детальніше ознайомлюсь:

Якщо список файлів вказаний як - @ ...

Тому я пробую це без -@, і щонайменше, обробляє його одразу, не натискаючи Ctrl+, Dале мені залишається однакова помилка .

На щастя, я знайшов коментар до відповіді на майже незв'язане запитання, яке дало мені зрозуміти, що мені потрібно явно назвати zip-файл. Ця помилка була, тому що за замовчуванням вона намагалася створити zip-файл під назвою zip.lst. Але оскільки це назва мого списку, можна подумати, що він просто його перезаписає, але ні, насправді він намагався оновити його. І оскільки список очевидно не є поштовим файлом, ми отримуємо помилкову помилку в структурі файлу, і тепер зрозуміло, чому він сказав "напевно, не zip-файл". Тож я спробував:

zip files.zip zip.lst

adding: zip.lst (deflated 35%)

Еврика! Я бачу, як створено zip-файл, і моя папка тепер містить це:

.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
├── files.zip
├── test.jpg
└── zip.lst

Але зачекайте, перш ніж святкувати, давайте спочатку підтвердимо вміст zip-файлу:

unzip -l files.zip

Archive:  files.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       48  2016-05-24 15:30   zip.lst
---------                     -------
       48                     1 file

Ні! Ну, насправді це має сенс від звичайного використання, тому що він просто зашпаркував один список файлів, який я йому дав. Нарешті я спробував ще раз, -@але отримав той же результат.

Що я роблю неправильно?

До речі, я знаю, що можу використовувати графічний інтерфейс і робити це за допомогою миші, але мені потрібно це скриптувати, і взагалі я швидший за CLI, коли знаю, що роблю.

Відповіді:


23

Використовуйте <перенаправлення файлів

zip files.zip -@ < zip.lst

Або ви можете пропустити список і просто глобус

zip files.zip *.txt *.jpg

спасибі steeldriver

Історична відповідь

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

Врешті-решт я виявив правильну відповідь , але вона була розміщена на неправильному питанні .

Кілька пунктів ясності:

  • Посібник не посилається на буквальний список, як у файлі, а буквально на перелік файлів на консолі.
  • Зрозуміло, що хтось може бути введений в оману, що fooпосилається на список файлів, але насправді він призначений представляти ім'я вихідного zip-файлу.
  • Список файлів у прикладі опущений, оскільки він використовує -@перемикач, який демонструє, що "приймає список вхідних файлів зі стандартного вводу замість командного рядка "

Розуміючи це, ми зараз озброєні різноманітними способами досягнення мети.

По-перше, використовуючи створений нами список файлів, ми можемо зчитувати список із catта перенаправляти вихід за допомогою труби як стандартного вводу на zip:

cat zip.lst | zip -@ files.zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

Побачивши, що adding: ...для кожного файлу це, безумовно, хороший знак, але ми сподівалися раніше, тому давайте просто підтвердимо:

unzip -l files.zip

Archive:  files.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2016-05-24 14:54   file1.txt
        0  2016-05-24 14:54   file2.txt
        0  2016-05-24 14:54   file3.txt
        0  2016-05-24 15:00   file.jpg
        0  2016-05-24 14:59   test.jpg
---------                     -------
        0                     5 files

СЛАДКА! Але хто хоче створити список одноразового використання? Це жахливий спосіб вирішення конкретного сценарію. Було б краще отримати список lsта передавати його на zip:

ls | zip -@ files.zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

Казкові! Тепер давайте створимо фільтри з приголомшливою потужністю, grepщоб просто зафіксувати, наприклад, jpg:

ls | grep .jpg | zip -@ images.zip

  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

Або просто файли, що починаються з "файл"

ls | grep file. | zip -@ files.zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)

5
Замість використання lsта grepта zip -@, ви можете використовувати глобуси оболонки для вибору файлів безпосередньо у командному рядку zip, наприклад, zip files.zip file*або zip images.zip *.jpg. Також, використовуючи список імен файлів з файлу, ви можете використовувати перенаправлення замість того, щоб викликати окремий процес кішки,zip files.zip -@ < zip.lst
steeldriver

Як ви можете зробити цю роботу з вкладеними каталогами поряд з файлами?
BallpointBen

@BallpointBen Я б використав findзамістьls
Джефф Пукетт

6

найпростіша команда з максимальним рівнем стиснення

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