Esiste un modo per comprimere tutti i file in una determinata directory con il comando zip
? “Ho sentito parlare dellutilizzo di *.*
, ma voglio che funzioni anche per i file senza estensione.
Commenti
- Hai provato a salire di un livello dalla directory desiderata e a fare
zip myarch.zip mydir/*
? - o meglio
zip -r myarch.zip mydir/*
- o migliore
zip -r myarch.zip mydir
-
*.*
indica qualsiasi file con un punto. In cp / m e dos tutti i file avevano un punto e ti ha fatto digitare (non si poteva*
). Pertanto le persone sono venute a vedere*.*
come tutti i file. Alla fine Microsoft ha aggiunto nomi di file lunghi che potrebbero avere zero o più punti. Per trovare un file che ha un punto su Windows devi digitare*.*.*
.
Risposta
Puoi semplicemente usare *
; non è necessario per *.*
. Le estensioni di file non sono speciali su Unix. *
corrisponde a zero o più ch caratteri, compreso un punto. Quindi corrisponde a foo.png
, perché si tratta di zero o più caratteri (sette, per lesattezza).
Tieni presente che *
per impostazione predefinita non “t corrisponde ai file che iniziano con un punto (né *.*
). Questo è spesso quello che vuoi. In caso contrario, in bash, se shopt -s dotglob
lo farà (ma escluderà comunque .
e ..
). Altre shell hanno modi diversi (o nessuno) di includere i dotfile.
In alternativa, zip
ha anche un -r
Opzione (ricorsiva) per creare interi alberi di directory contemporaneamente (senza doversi preoccupare del problema dei dotfile):
zip -r myfiles.zip mydir
dove mydir
è la directory contenente i tuoi file. Si noti che lo zip prodotto conterrà la struttura della directory oltre ai file. Come sottolinea Peterph nel suo commento, questo di solito è visto come una buona cosa: lestrazione dello zip memorizzerà ordinatamente tutti i file estratti in una sottodirectory.
Puoi anche dire a zip di non memorizzare i percorsi con il -j
/ --junk-paths
opzione.
Il comando zip
viene fornito con documentazione che ti informa su tutte le sue (molte) opzioni; digita man zip
per visualizzare la documentazione. Questo non è esclusivo di zip; puoi ottenere la documentazione per la maggior parte dei comandi in questo modo.
Commenti
sto facendo. ‘ t * non includerebbe.
e..
?
Risposta
Nel mio caso volevo comprimere ogni file nel proprio archivio, quindi ho fatto quanto segue (in zsh
):
$ for file in *; do zip ${file%.*}.zip $file; done
Commenti
- Ecco ‘ no
mkv
qui? Inoltre, nulla qui è particolarmentezsh
specifico. ‘ vorrai citare correttamente qualsiasi variabile contenente un nome file, quindizip "${file%.*}.zip" "$file"
con le virgolette doppie attorno a entrambe le variabili. - @tripleee Innanzitutto, grazie per aver segnalato il mio riferimento errato a
mkv
. In secondo luogo, la citazione di argomenti non è necessaria inzsh
, a differenza dibash
. Questo è ‘ perché ho specificato che questo era un comando perzsh
. - Sostituendo lultimo punto e virgola con una e commerciale potrebbe accelerarlo in modo significativo (se il numero di file nella directory è ragionevole …). Altrimenti
find . -type f -maxdepth 1 -print0|xargs -r0 -n1 -P64 -I{} bash -c 'f="{}"; zip "${f%.*}.zip" "$f"'
(con-P
regolato a seconda dei thread della CPU …) (Molte dipendenze GNU …) - per comprimere ogni file nel proprio archivio, eseguire
gzip *
Risposta
Un altro modo sarebbe usare find e xargs: (questo potrebbe includere una directory “.” nello zip, ma dovrebbe comunque essere estratto correttamente. Con il mio test, zip ha rimosso il punto prima compressione) find . -type f -exec zip zipfile.zip {} +
(+
può essere sostituito con \;
se la tua versione di find
non supporta +
end for exec. Sarà però più lenta …)
Questo includerà per impostazione predefinita tutte le sottodirectory. Su GNU, trovare -maxdepth
può impedirlo.
Commenti
- (a differenza delle soluzioni che utilizzano
*
, includerà dotfile e ‘ non cadrà se ci sono troppi file in una directory)
Answer
Un altro metodo (lento) per eseguire questa operazione (che aggiunge un file alla volta allo zip):
for f in * .[^.]*; do [ -r "$f" ] || continue # Skip directories or non-existant files (Probably ".[^.]*" if directory has no dotfiles). Using -e will allow directories to be used as well zip zipfile.zip "$f" # If directories are included, you probably want to add -r done
Questo presenta i problemi dotfile di *
(soluzione alternativa aggiunta) e dovrebbe essere avviato zip una volta per ogni file, aggiungendolo allarchivio. In bash
, gestiva una grande quantità di file.
Sarebbe più lento della maggior parte degli altri metodi, ma relativamente semplice.
Commenti
- Direi che è meno semplice della risposta accettata e più lenta, il che fa sorgere la domanda: ” Perché qualcuno dovrebbe farlo? “. Se puoi rispondere a questa domanda, ti consiglio di inserire quel contesto nella tua risposta, altrimenti penso che sia una cattiva risposta a una vecchia domanda che ha già una buona risposta.
- @Centimane: prendo atto dei limiti . Penso che questo abbia un valore educativo. (Se non si saltano le directory, è abbastanza semplice). Se desideri una risposta molto più rapida utilizzando invece uno strumento esterno (standard), la mia altra risposta lo copre . (con la gestione dei dotfile rimossa (che influisce sulla correttezza senza la loro assenza menzionata nella domanda), ritengo che sia abbastanza elegante):
for f in *; do zip zip.zip "$f"; done
- Nota che il accettato la risposta ‘ non utilizza un comando esterno e sarebbe più veloce. In quale scenario sarebbe utile questa risposta?
- @Centimane Con tar quando ci sono più file di quelli che bash può passare come parametri. (find + xargs sono migliori, perché i loop sono più facili …). È una risposta (unica) alla domanda. Non è certo la risposta ottimale. (Le risposte non ottimali possono ancora essere utili per problemi simili, se qualcuno ha una situazione leggermente diversa, ad esempio se si desidera che il file tar abbia una directory in esso)
*
shell-globbing non ‘ include dotfile (cioè nomi di file che iniziano con.
). Questo è un altro vantaggio di zippare lintera directory per nome.