大量のファイルを個別に圧縮したい
手元にある雑多なファイルをS3のGlacier Deep Archiveに入れたいのですが、長期保存前提でファイル中身を見るには時間とお金がかかります。フォルダごと圧縮してしまうとフォルダに入っているファイルが何か調べるのにフォルダをダウンロードしなければならず効率が悪いです。
フォルダ中に入っているファイルをフォルダごと圧縮ではなく、ファイルごとに圧縮したいのですが、Explzhなどのソフトではうまくできません。
そこでプロンプト上からバッチ処理で個別に圧縮することにしました。
7zipは圧縮率が高い
圧縮形式はzipが最も汎用性が高いですが、圧縮率でいうとwindowsではcabや7zip、linuxではbzip2が良さそうです。本当はどれが良いか比較しようと思いましたが、圧縮率はそこまで変わらないだろうから、7zipにしました。
windowsのpowershellは使い慣れていないのでwslのlinux上で圧縮します。
wslのubuntu上で7zipをインストール
ubuntu上でも7zipのパッケージが利用できます。
# apt search 7zip 2> /dev/null | grep 7zip
7zip/jammy 21.07+dfsg-4 amd64
p7zip/jammy 16.02+dfsg-8 amd64
p7zip-full/jammy 16.02+dfsg-8 amd64
p7zip-rar/jammy 16.02-3build1 amd64
non-free rar module for p7zip
### fullをインストールする
# apt install p7zip-full
7zipはLinuxのオーナー/グループの保存に対応していないのでlinuxのアーカイバに利用しないように
・7zipのmanより
Backup and limitations
DO NOT USE the 7-zip format for backup purpose on Linux/Unix because :
- 7-zip does not store the owner/group of the file.
On Linux/Unix, in order to backup directories you must use tar :
- to backup a directory : tar cf - directory | 7z a -si directory.tar.7z
- to restore your backup : 7z x -so directory.tar.7z | tar xf -
If you want to send files and directories (not the owner of file) to others Unix/MacOS/Win‐
dows users, you can use the 7-zip format.
Linux版7zipの使い方
Linux版7zipのコマンドは7zです。
7zの使い方はmanのEXAMPLE1を見てみましょう。
色々指定していますがコマンドとしては「7z a -mx=9 {圧縮ファイル名.7z} {圧縮する対象ファイル}」でできます。
EXAMPLE 1
7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on archive.7z dir1
adds all files from directory "dir1" to archive archive.7z using "ultra settings"
-t7z 7z archive (7zアーカイバの指定 なくて良さそう)
-m0=lzma
lzma method
-mx=9 level of compression = 9 (Ultra)
-mfb=64
number of fast bytes for LZMA = 64
-md=32m
dictionary size = 32 megabytes
-ms=on solid archive = on
実際にワンライナーで対象ディレクトリのファイルを圧縮してみました
ls -1 ./test2/ | while read file ; do 7z a -mx=9 ./test2/"${file}".7z ./test2/"${file}" ;done
findコマンドを使ってwindowsにマウントされているcドライブのfile_tmpフォルダ配下にある全てのファイルを7zに圧縮して圧縮元のファイルを削除(-sdelオプション)するワンライナー
find /mnt/c/file_tmp/ $(pwd) -type f |grep -v ".7z$"| while read file ; do 7z a -mx=9 -sdel "${file}".7z "${file}" ; done
↓のコマンドでテストしてfindの出力結果の3つだけを圧縮したので上のワンライナーでは 7zを除外してますが初めてならいらないと思います。除外したい形式があればgrep -v の所で除外しましょう。
find /mnt/c/file_tmp/ $(pwd) -type f |head -n3 | while read file ; do 7z a -mx=9 -sdel "${file}".7z "${file}" ; done
目的のファイルがマッチしてるかを十分に確認してから実行してください。-sdelが入っているので元ファイルは削除されます。気をつけてください。