ディレクトリ内のすべてのファイルを圧縮しますか?


483

zipコマンドで特定のディレクトリ内のすべてのファイルを圧縮する方法はありますか?を使用したことを聞いたことがあり*.*ますが、拡張子のないファイルでも動作するようにしたいのです。


2
目的のディレクトリから1レベル上に移動してみましたzip myarch.zip mydir/*か?
ジョセフR.

13
またはより良いzip -r myarch.zip mydir/*
アダム

25
またはそれ以上zip -r myarch.zip mydir
ctrl-alt-delor

*.*ドットのあるファイルを意味します。cp / mおよびdosでは、すべてのファイルにドットがあり、入力できました(できませんでした*)。したがって、人々は*.*すべてのファイルを見るようになりました。最終的に、Microsoftはゼロまたはそれ以上のドットを持つ可能性のある長いファイル名を追加しました。Windowsでドットを含むファイルを見つけるには、と入力する必要があります*.*.*
ctrl-alt-delor

回答:


705

ただ使用できます*。必要はありません*.*。Unixでは、ファイル拡張子は特別ではありません。*0個以上の文字(ドットを含む)に一致します。foo.pngゼロ以上の文字(正確には7)であるため、一致します。

ことに注意してください*(どちらも行わない、デフォルトでは、ドットで始まるファイルと一致していません*.*)。これはたいていあなたが望むものです。そうでない場合、bashで、あなたがshopt -s dotglobそうするでしょう(しかし、それでも除外.します..)。他のシェルには、ドットファイルを含める方法が異なります(またはまったくありません)。

または、ディレクトリツリー全体を一度に実行zipする-r(再帰的な)オプションもあります(ドットファイルの問題を心配する必要はありません)。

zip -r myfiles.zip mydir

どこにmydirファイルが含まれているディレクトリです。生成されたzipには、ディレクトリ構造とファイルが含まれることに注意してください。peterphがコメントで指摘しているように、これは通常良いことと見なされています。zipを抽出すると、抽出されたすべてのファイルが1つのサブディレクトリにきちんと保存されます。

-j/ --junk-pathsオプションを使用して、zipにパスを保存しないように指示することもできます。

このzipコマンドには、すべての(多くの)オプションについて説明するドキュメントが付属しています。入力man zipしてそのドキュメントを表示します。これはzipに固有のものではありません。この方法でほとんどのコマンドのドキュメントを入手できます。


9
アーカイブのすべてを最上位ディレクトリに含めることをお勧めします-抽出時に現在のディレクトリを汚染しないように追加することをお勧めします。
ペテルフ

@peterph完了。これは、zipファイルでは、たとえばtarfilesほど慣習ではありませんが、怖いです。
デロバート

残念ながらそうです。おそらく、デスクトップへのドラッグアンドドロップのWindowsの遺産と、ソースコードを操作するLinuxの遺産が原因です。
ペテルフ

2
*シェルグロビングにはドットファイル(つまり、で始まるファイル名.)は含まれないことに注意してください。これは、ディレクトリ全体を名前で圧縮する別の利点です。
-mrb

しかし、-rを使用するとディレクトリ自体が含まれるため、私がやっていることを壊してしまいます。*含まれないだろう...
tkbx

11

私の場合、各ファイルを独自のアーカイブに圧縮したいので、次のことを行いました(zsh):

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

1
mkvここはありませんか?また、ここでは特に特定のものはありませんzsh。ファイル名を含む変数は適切に引用する必要があるためzip "${file%.*}.zip" "$file"、両方の変数を二重引用符で囲みます。
トリプリー

1
@tripleeeまず、私の誤った参照を指摘してくれてありがとうmkv。第二に、のzsh場合とは異なり、引数の引用は不要bashです。そのため、これはのコマンドであると指定しましたzsh
ラドンロズバラ

最後のセミコロンをアンパサンドに置き換えると、大幅に高速化される場合があります(ディレクトリ内のファイルの数が妥当な場合...)。それ以外の場合find . -type f -maxdepth 1 -print0|xargs -r0 -n1 -P64 -I{} bash -c 'f="{}"; zip "${f%.*}.zip" "$f"'-PCPUスレッドに応じて調整...)(多くのGNU依存関係...)
Gert van den Berg

5

別の方法は、findとxargsを使用することです(これには、zipに「。」ディレクトリが含まれる場合がありますが、それでも正しく解凍されるはずです。私のテストでは、zipは圧縮前にドットを削除しました) find . -type f -exec zip zipfile.zip {} +

(のバージョンがexec の終了をサポートしていない場合、に+置き換えることができます。しかし、より遅くなります...)\;find+

これにはデフォルトですべてのサブディレクトリが含まれます。GNUのfindではそれ-maxdepthを防ぐことができます。


(使用したソリューションとは異なり*、これはドットファイルが含まれますし、あまりにも多くのファイルがディレクトリに存在する場合倒れません)
ゲルトファンデンベルグ

1

これを行う別の(遅い)メソッド(一度に1つのファイルを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

これには*(回避策が追加された)のドットファイルの問題があり、各ファイルに対して1回ずつzipを開始し、アーカイブに追加します。ではbash、大量のファイルを処理します。

他のほとんどの方法よりも遅くなりますが、比較的簡単です。


1
私はこれが受け入れられた答えよりも単純ではなく、遅く、「なぜ誰がこれをするのか?」という質問を促します。もしあなたがその質問に答えることができるなら、私はあなたの答えにその文脈を入れることを勧めます。さもなければ、私はそれがすでに良い答えを持っている古い質問に対する悪い答えだと思います。
-Centimane

@Centimane:制限に注意します。これには教育的価値があると思う。(ディレクトリをスキップしない場合、それは非常に簡単です)。代わりに(標準の)外部ツールを使用してはるかに高速な回答が必要な場合は、他の回答で対応します。(ドットファイルの処理を削除すると(質問で言及されていない正確さに影響します)、非常にエレガントであると感じます):for f in *; do zip zip.zip "$f"; done
Gert van den Berg

1
受け入れられた答えは外部コマンドを使用せず、より高速になることに注意してください。この答えはどのシナリオで役立ちますか?
Centimane

@Centimane bashがパラメーターとして渡すことができるものよりも多くのファイルがある場合、tarを使用します。(find + xargsの方が優れています。forループの方が簡単です...)。これは、質問に対する(一意の)回答です。それは確かに最適な答えではありません。(最適化されていない回答は、誰かが少し異なる状況を持っている場合、同様の問題に役立ちます。たとえば、tarファイルにディレクトリを入れたい場合)
Gert van den Berg
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.