Există o modalitate de a zip toate fișierele dintr-un director dat cu comanda zip? „Am auzit de utilizarea *.*, dar vreau să funcționeze și pentru fișiere fără extensii.

Comentarii

  • Ați încercat să navigați la un nivel în sus din directorul dorit și să faceți zip myarch.zip mydir/*?
  • sau mai bine zip -r myarch.zip mydir/*
  • sau mai bun zip -r myarch.zip mydir
  • *.* înseamnă orice fișier cu punct. În cp / m și dos toate fișierele aveau un punct și vă făcea să îl tastați (nu a putut face *). Prin urmare, oamenii au venit să vadă *.* ca toate fișierele. În cele din urmă, Microsoft a adăugat nume de fișiere lungi care ar putea avea zero sau mai multe puncte. Pentru a găsi un fișier care are un punct pe Windows trebuie să tastați *.*.*.

Răspuns

Puteți folosi doar *; nu este nevoie pentru *.*. Extensiile de fișiere nu sunt speciale pe Unix. * se potrivește cu zero sau mai multe ch caractere – inclusiv un punct. Deci, se potrivește cu foo.png, deoarece acesta are zero sau mai multe caractere (șapte, mai exact).

Rețineți că * implicit nu se potrivește cu fișierele care încep cu un punct (nici *.*) nu corespunde. De multe ori asta vrei. Dacă nu, în bash, dacă shopt -s dotglob va fi (dar va exclude totuși . și ..). Alte cochilii au moduri diferite (sau deloc) de a include fișierele dot.

Alternativ, zip are și un -r (recursiv) opțiune pentru a face copaci întregi de directori simultan (și nu trebuie să vă faceți griji cu privire la problema dotfile):

zip -r myfiles.zip mydir 

unde mydir este directorul care conține fișierele dvs. Rețineți că fișierul zip produs va conține structura directorului, precum și fișierele. După cum subliniază Peter în comentariul său, acest lucru este de obicei văzut ca un lucru bun: extragerea zip-ului va stoca cu grijă toate fișierele extrase într-un singur subdirector.

De asemenea, puteți spune zip-ului să nu stocheze căile cu -j / --junk-paths opțiune.

Comanda zip vine cu documentație care vă spune despre toate (multe) opțiuni; tastați man zip pentru a vedea documentația respectivă. Acest lucru nu este unic pentru zip; puteți obține documentația pentru majoritatea comenzilor în acest fel.

Comentarii

  • S-ar putea să doriți să adăugați, că este a considerat o bună practică să conțină tot ce se află în arhivă într-un director de nivel superior – astfel încât să nu

să-și polueze directorul curent la extragere.

  • @peterph făcut. Deși aceasta este mai puțin o convenție în fișierele zip decât în, de exemplu, tarfile, îmi este ‘ tem.
  • din păcate da. Probabil din cauza ferestrelor moștenire de drag ‘ n ‘ drop pe desktop și linux moștenire de lucru cu coduri sursă.
  • Păstrați în rețineți că * shell-globbing nu include ‘ nu include fișiere dot (de exemplu, numele fișierelor care încep cu .). Acesta este un alt avantaj pentru a arhiva întregul director după nume.
  • Dar folosind -r include directorul în sine, care rupe ceea ce I ‘ m doing. ‘ t * nu ar include . și ..?
  • Răspuns

    În cazul meu, am vrut să zip fiecare fișier în propria arhivă, așa că am făcut următoarele (în zsh):

    $ for file in *; do zip ${file%.*}.zip $file; done 

    Comentarii

    • Acolo ‘ s nu mkv aici? De asemenea, nimic aici nu este specific zsh. ‘ veți dori să citați în mod corespunzător orice variabilă care conține un nume de fișier, deci zip "${file%.*}.zip" "$file" cu ghilimele duble în jurul ambelor variabile.
    • @tripleee În primul rând, mulțumesc că mi-ați indicat referința eronată la mkv. În al doilea rând, citarea argumentelor nu este necesară în zsh, spre deosebire de bash. Acesta este ‘ motivul pentru care am specificat că aceasta este o comandă pentru zsh.
    • Înlocuirea ultimului punct și virgulă cu un semn comercial poate accelera semnificativ (Dacă numărul de fișiere din director este rezonabil …). În caz contrar, find . -type f -maxdepth 1 -print0|xargs -r0 -n1 -P64 -I{} bash -c 'f="{}"; zip "${f%.*}.zip" "$f"' (cu -P ajustat în funcție de firele de procesare ale dvs. …) (Multe dependențe GNU …)
    • pentru a zip fiecare fișier în propria arhivă, faceți gzip *

    Răspundeți

    O altă modalitate ar fi să folosiți find și xargs: (acesta ar putea include un director „.” în zip, dar ar trebui să fie extras corect. Cu testul meu, zip a dezlipit punctul înainte compresie) find . -type f -exec zip zipfile.zip {} +

    (+ poate fi înlocuit cu \; dacă versiunea dvs. de find nu acceptă sfârșitul + pentru execut. Va fi totuși mai lent …)

    Aceasta va include în mod implicit toate subdirectoarele. În GNU find -maxdepth poate împiedica acest lucru.

    Comentarii

    • (spre deosebire de soluțiile care utilizează *, acesta va include dotfiles și nu va cădea ‘ dacă nu există prea multe fișiere într-un director)

    Răspuns

    O altă metodă (lentă) pentru a face acest lucru (care adaugă un fișier la fișierul zip la un moment dat):

    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 

    Acesta are problemele cu fișierul dot al * (soluție adăugată) și ar fi pornit zip o dată pentru fiecare fișier, adăugându-l la arhivă. În bash, se va ocupa de o cantitate mare de fișiere.

    Ar fi mai lent decât majoritatea celorlalte metode, dar este relativ simplu.

    Comentarii

    • Aș spune că acest lucru este mai puțin simplu decât răspunsul acceptat și mai lent, ceea ce determină întrebarea: ” De ce ar face cineva acest lucru? „. Dacă puteți răspunde la această întrebare, vă recomand să puneți contextul respectiv în răspunsul dvs., altfel cred că este un răspuns rău la o întrebare veche care are deja un răspuns bun.
    • @Centimane: Observ limitele . Simt că acest lucru are valoare educațională. (Dacă nu săriți directoare, este destul de simplu). Dacă doriți un răspuns mult mai rapid folosind un instrument extern (standard), celălalt răspuns al meu acoperă acest lucru. (cu manipularea fișierelor dot eliminată (ceea ce afectează corectitudinea fără absența lor menționată în întrebare), consider că este destul de elegant): for f in *; do zip zip.zip "$f"; done
    • Rețineți că răspunsul nu ‘ nu folosește o comandă externă și ar fi mai rapid. În ce scenariu ar fi util acest răspuns?
    • @Centimane Cu tar atunci când există mai multe fișiere decât ceea ce bash poate trece ca parametri. (găsiți + xargs sunt mai bune, pentru că buclele sunt mai ușoare …). Este un răspuns (unic) la întrebare. Cu siguranță nu este răspunsul optim. (Răspunsurile neoptimale pot fi în continuare utile pentru probleme similare, dacă cineva are o situație ușor diferită – de exemplu, dorește fișierul tar orice directoare din acesta)

    Lasă un răspuns

    Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *