¿Cómo crear un zip con múltiples archivos sin subcarpetas?

12

Situación inicial:

.
├── d0
├── f0
├── f1
│   └── d1
└── f2
    └── f3
        ├── d2
        ├── d3
        └── d4

Lo que necesito hacer:

Me gustaría crear un zip que contenga d0, d1 y d4 que debe tener la siguiente estructura:

.
├── d0
├── d1
└── d4

Lo que ya he probado:

Lo he probado con zip myfiles d0 f1/d1 f2/f3/d4. Pero esto mantiene la estructura de carpetas original, que no es lo que quiero.

.
├── d0
├── f1
│   └── d1
└── f2
    └── f3
        └── d4

Pregunta ¿Cómo crear un zip con múltiples archivos sin las subcarpetas?

eDeviser
fuente

Respuestas:

17

Manualmente, puede crear el archivo zip y actualizarlo:

zip myfiles d0
(cd f1; zip -u ../myfiles.zip d1)
(cd f2/f3; zip -u ../../myfiles.zip d4)

Los paréntesis crean subcapas, y el efecto de la cdúnica dura en la subcapa, por lo que no tiene que cdvolver al directorio original.

Si d1, d2etc. son en realidad archivos y no directorios en sí, entonces use la -jopción:

-j
--junk -paths
Almacena solo el nombre de un archivo guardado (basura la ruta), y no almacena nombres de directorio. Por defecto, zip almacenará la ruta completa (relativa al directorio actual).

muru
fuente
19

Puede usar findpara obtener la lista de archivos y ejecutarlos zip -j myfilespara empaquetarlos ignorando las rutas:

find . -name "d[014]" -exec zip -j myfiles {} +

Ejemplo

$ tree
.
├── d0
├── f0
├── f1
│   └── d1
└── f2
    └── f3
        ├── d2
        ├── d3
        └── d4

$ find . -name "d[014]" -exec zip -j myfiles {} +
  adding: d1 (stored 0%)
  adding: d4 (stored 0%)
  adding: d0 (stored 0%)

$ unzip -l myfiles.zip
Archive:  myfiles.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2017-10-09 10:47   d1
        0  2017-10-09 10:48   d4
        0  2017-10-09 10:47   d0
---------                     -------
        0                     3 files

Sin embargo, esto funciona solo para archivos , los directorios serán ignorados por zip -j. Para que esto funcione también para los directorios, digamos que queremos empacar d0, d1y todo el f3directorio en el ejemplo anterior, la findlínea se vuelve un poco más complicada:

$ find . \( -name "d[01]" -o -name "f3" \) -exec sh -c 'p=$(pwd); for i in $0 $@; do cd ${i%/*}; zip -ur "$p"/myfiles ${i##*/}; cd "$p"; done' {} +
        zip warning: /home/dessert/myfiles.zip not found or empty
  adding: d1 (stored 0%)
  adding: f3/ (stored 0%)
  adding: f3/d3 (stored 0%)
  adding: f3/d2 (stored 0%)
  adding: f3/d4 (stored 0%)
  adding: d0 (stored 0%)
$ unzip -l myfiles.zip 
Archive:  myfiles.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2017-10-11 10:18   d1
        0  2017-10-11 10:19   f3/
        0  2017-10-11 10:19   f3/d3
        0  2017-10-11 10:19   f3/d2
        0  2017-10-11 10:19   f3/d4
        0  2017-10-11 10:17   d0
---------                     -------
        0                     6 files
postre
fuente
18

El uso de la opción -j eliminará la ruta del archivo.

zip -j myfiles d0 f1/d1 f2/f3/d4 

referencia

ravery
fuente
Si alguna de las rutas que está pasando no son archivos sino directorios, esos directorios no se agregarán al ziparchivo con la -jopción.
Dan
@dan: si desea que todos los archivos estén en un directorio sin la rutazip -j myfiles directory/*
ravery el