Existuje způsob, jak pomocí příkazu zip komprimovat všechny soubory v daném adresáři? Slyšel jsem o používání *.*, ale chci, aby to fungovalo i pro soubory bez přípony.

Komentáře

  • Zkusili jste přejít o úroveň výš z požadovaného adresáře a udělat zip myarch.zip mydir/*?
  • nebo lépe zip -r myarch.zip mydir/*
  • nebo lepší zip -r myarch.zip mydir
  • *.* znamená jakýkoli soubor s tečkou. cp / ma dos všechny soubory měly tečku a vy jste je museli psát (nemohlo to *). Lidé se proto přišli podívat *.* jako všechny soubory. Microsoft nakonec přidal názvy dlouhých souborů, které by mohly mít nulu nebo více teček. Chcete-li najít soubor, který má tečku v systému Windows, musíte zadat *.*.*.

Odpověď

Stačí použít *; není třeba pro *.*. Přípony souborů nejsou v Unixu speciální. * odpovídá nule nebo více ch přízraky – včetně tečky. Odpovídá tedy foo.png, protože to má nula nebo více znaků (přesněji sedm).

Všimněte si, že * ve výchozím nastavení neodpovídá souborům začínajícím tečkou (*.*). To je často to, co chcete. Pokud ne, v bash, pokud shopt -s dotglob to uděláte (ale stále bude vylučovat . a ..). Jiné skořápky mají různé způsoby (nebo vůbec žádné) zahrnutí dotfile.

Alternativně zip má také -r (rekurzivní) možnost dělat celé adresářové stromy najednou (a nemusíte se starat o problém s dotfile):

zip -r myfiles.zip mydir 

kde mydir je adresář obsahující vaše soubory. Všimněte si, že vytvořený zip bude obsahovat adresářovou strukturu i soubory. Jak Peter poznamenává ve svém komentáři, obvykle je to považováno za dobrou věc: extrahování zipu úhledně uloží všechny extrahované soubory do jednoho podadresáře.

Můžete také říct zipu, aby neukládal cesty s -j / --junk-paths možnost.

Příkaz zip je dodáván s dokumentace, která vás informuje o všech jejích (mnoha) možnostech; zadejte man zip a podívejte se na tuto dokumentaci. Toto není jedinečné pro zip; dokumentaci pro většinu příkazů získáte tímto způsobem.

Komentáře

  • Možná budete chtít přidat, že je považováno za osvědčený postup obsahovat vše v archivu v adresáři nejvyšší úrovně – aby neznečisťoval ‚ jeho aktuální adresář extrakcí.
  • @peterph hotovo. I když se jedná o menší konvenci v zip souborech než např. v tarfile, bojím se ‚.
  • bohužel ano. Pravděpodobně kvůli oknům dědictví drag ‚ n ‚ přejít na plochu a linuxové dědictví práce se zdrojovými kódy.
  • Ponechat pamatujte, že * shell globbing neobsahuje ‚ t dotfiles (tj. názvy souborů začínající .). To je další výhoda zipování celého adresáře podle názvu.
  • Ale použití -r zahrnuje samotný adresář, který rozbíjí to, co jsem ‚ dělám. Nebyl by ‚ t * zahrnut . a ..?

Odpověď

V mém případě jsem chtěl zazipovat každý soubor do vlastního archivu, takže jsem udělal následující (v zsh):

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

Komentáře

  • Tam ‚ s ne mkv zde? Také zde nic není zvlášť zsh -specifické. ‚ Budete chtít řádně citovat jakoukoli proměnnou obsahující název souboru, takže zip "${file%.*}.zip" "$file" uvést uvozovky kolem obou proměnných.
  • @tripleee Za prvé, děkuji za poukázání na můj chybný odkaz na mkv. Zadruhé, citování argumentů je v zsh zbytečné, na rozdíl od bash. Proto jsem ‚ uvedl, že se jedná o příkaz pro zsh.
  • Výměna posledního středníku za ampersand by to mohl výrazně zrychlit (pokud je počet souborů v adresáři přiměřený …). Jinak find . -type f -maxdepth 1 -print0|xargs -r0 -n1 -P64 -I{} bash -c 'f="{}"; zip "${f%.*}.zip" "$f"' (s úpravou -P v závislosti na vašich vláknech CPU …) (Mnoho závislostí GNU …)
  • Chcete-li každý soubor zazipovat do vlastního archivu, proveďte gzip *

odpověď

Jiným způsobem by bylo použití find a xargs: (to může zahrnovat adresář „.“ v zipu, ale stále by se měl správně extrahovat. S mým testem zip před tím odstranil tečku komprese) find . -type f -exec zip zipfile.zip {} +

(+ lze nahradit \; pokud vaše verze find nepodporuje konec + pro exec. Bude to ale pomalejší …)

Ve výchozím nastavení budou zahrnuty všechny podadresáře. Na GNU tomu může -maxdepth zabránit.

Komentáře

  • (na rozdíl od řešení využívajících *, bude to zahrnovat dotfiles a ‚ nepřekročí, pokud je v adresáři příliš mnoho souborů)

Odpovědět

Další (pomalá) metoda, jak toho dosáhnout (která přidává do zipu po jednom souboru):

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 

Toto má problémy se souborem dotfile * (přidáno řešení) a pro každý soubor by se spustil zip jednou, což by jej přidalo do archivu. V bash by se zabýval velkým množstvím souborů.

Bylo by to pomalejší než u většiny ostatních metod, ale je to relativně jednoduché.

Komentáře

  • Řekl bych, že je to méně jednoduché než přijatá odpověď a pomalejší, což vyvolává otázku: “ Proč by to někdo dělal? „. Pokud na tuto otázku můžete odpovědět, doporučuji vám, abyste do své odpovědi vložili tento kontext, jinak si myslím, že je to špatná odpověď na starou otázku, která již má dobrou odpověď.
  • @Centimane: Beru na vědomí omezení . Cítím, že to má vzdělávací hodnotu. (Pokud nepřeskočíte adresáře, je to docela jednoduché). Pokud chcete mnohem rychlejší odpověď pomocí (standardního) externího nástroje, moje další odpověď pokrývá to. (s odstraněnou manipulací s dotfiles (což ovlivňuje správnost bez jejich nepřítomnosti zmíněné v otázce) mám pocit, že je to celkem elegantní): for f in *; do zip zip.zip "$f"; done
  • Všimněte si, že přijatý odpověď nepoužívá ‚ t externí příkaz a byla by rychlejší. V jakém scénáři by byla tato odpověď užitečná?
  • @Centimane With tar when there are more files than what bash can pass as parameters. (find + xargs jsou lepší, protože smyčky jsou jednodušší …). Je to (jedinečná) odpověď na otázku. Určitě to není optimální odpověď. (Neoptimální odpovědi mohou být stále užitečné pro podobné problémy, pokud má někdo trochu jinou situaci – např. Chce, aby soubor tar obsahoval nějaké adresáře)

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *