Как указать имена файлов в zip при создании в командной строке из канала?
Я пытаюсь создать zip файл из содержимого файла, на который подается канал, например.
mysql [params and query] | zip -q output.zip -
Это правильно пишет zip, но когда вы открываете zip, файл внутри него называется "-". Есть ли способ указать, что имя файла в каналах данных должно быть в zip файле?
Ответы
Ответ 1
Из того, что я могу собрать, вы не можете обойтись с командой zip
, я имею в виду, что вы не можете указывать имена файлов и передавать контент. Вы можете либо передать содержимое, и результирующий файл -
, либо вы можете передать имена файлов с помощью [email protected]
.
Это не значит, что делать это невозможно с помощью других методов. Я излагаю один из приведенных ниже. Это означает, что у вас должен быть установлен PHP и добавлен zip-расширение.
Там может быть целая куча других способов сделать это. Но это самый легкий, о котором я знаю. О, это тоже однострочный.
Это рабочий пример с использованием PHP
echo contents | php -r '$z = new ZipArchive();$z->open($argv[1],ZipArchive::CREATE);$z->addFromString($argv[2],file_get_contents("php://stdin"));$z->close();' test.zip testfile
Для запуска на окнах просто свопите одиночные и двойные кавычки. Или просто поместите script в файл.
"test.zip" - это полученный Zip файл, "testfile" - это имя содержимого, которое передается в команду.
Результат от unzip -l test.zip
Archive: test.zip
Length Date Time Name
--------- ---------- ----- ----
6 01-07-2010 12:56 testfile
--------- -------
6 1 file
И вот рабочий пример с использованием python
echo contents | python -c "import sys
import zipfile
z = zipfile.ZipFile(sys.argv[1],'w')
z.writestr(sys.argv[2],sys.stdin.read())
z.close()
" test5.zip testfile2
Результат unzip -l
Archive: test5.zip
Length Date Time Name
-------- ---- ---- ----
9 01-07-10 13:43 testfile2
-------- -------
9 1 file
Результат unzip -p
contents
Ответ 2
Вы можете сделать это.
ls | zip test.zip [email protected]
это делается из понятия, что у меня есть 3 файла в каталоге.
-rw-rw-r-- 1 xxx domain users 6 Jan 7 11:41 test1.txt
-rw-rw-r-- 1 xxx domain users 6 Jan 7 11:41 test2.txt
-rw-rw-r-- 1 xxx domain users 6 Jan 7 11:41 test3.txt
и самого файла, результатом будет
Archive: test.zip
Length Date Time Name
-------- ---- ---- ----
6 01-07-10 11:41 test1.txt
6 01-07-10 11:41 test2.txt
6 01-07-10 11:41 test3.txt
-------- -------
18 3 files
На странице Linux Zip Man
Если список файлов указан как - @, zip принимает список входных файлов от стандартного ввода.
Ответ 3
Вы можете использовать именованный канал и отправить на него вывод запроса, при этом записясь с него.
mkfifo output.txt ; mysql [params and query] > output.txt & zip output.zip -FI output.txt ; rm output.txt
Ответ 4
Мне не удалось справиться с ответом PHP (из памяти на больших дампах mysql), и FIFO не работал так, как я хотел, поэтому мое решение переименовать файл внутри ZIP-архива после запуска дампа, используя zipnote (который включен в пакет zip на Debian).
mysql [params and query] | zip -q output.zip -
echo -e "@ -\[email protected]=newname.sql" | zipnote -w output.zip
Ответ 5
mysql [params and query] | python3 -c "import sys as s,os,zipfile as m;z=m.ZipFile(os.fdopen(s.stdout.fileno(),'wb'),'w');z.writestr(s.argv[1],s.stdin.read());z.close()" 'filename.sql' > output.zip
В Python 3.5 добавлена поддержка записи в невидимые потоки.
Это не красиво, но работает.
Ответ 6
Ты можешь попробовать:
mysql [params and query] | zip -q output.zip [email protected]