LoginSignup
2
2

More than 3 years have passed since last update.

bashでforループを使ってzip圧縮

Last updated at Posted at 2020-02-22

背景

普段ファイルをzip圧縮したい時は、コマンドラインから下記の様に処理していました。

bash
# テキストファイルsample01.txtをsample01.zipに圧縮
$ zip sample01.zip sample01.txt

しかし、この処理を大量のファイルに対して圧縮及び採番するとなるとあまりにも面倒(というか非現実的)な為、bashでforループ回せないかな?と思って調べたことをメモります。

bashでforループ

まずはbash上でのforループの構文を確認。

bash
$ for 変数 in 値リスト
> do
> なんか処理
> done

となります。意外とシンプル。
例えば、forループお決まりの0から9までの数字を出力する例だと

bash
$ for i in 0 1 2 3 4 5 6 7 8 9
> do
> echo $i
> done

もしくは

bash
$ for i in `seq 0 9`
> do
> echo $i
> done
出力結果
0
1
2
3
4
5
6
7
8
9

となります。

sample01.txt ~ sample50.txtを1つずつzip圧縮

さて、本題に入ります。
連番で名前が付いているファイルを1つずつ圧縮するには上記のfor文を使うのですが、桁数の都合上01から09までと10から50までの処理を分ける必要があります。
ifで分岐して処理しても良いのですが、そんなにしょっちゅう使うものでもないしなぁ、ということでご容赦下さい。以下のように書きます。
※他に何か良い方法があれば是非教えて下さい!

bash
$ for i in `seq 1 9`
> do
> zip sample0$i.zip sample0$i.txt
> done
bash
$ for i in `seq 10 50`
> do
> zip sample$i.zip sample$i.txt
> done

これでsample01.zip ~ sample50.zipが作成されているはずです!

2020/02/23追記:1回の処理で圧縮する!

@kkdd さんにアドバイス頂き、以下のコマンドで一括で処理できるようになりました!
ありがとうございました!

bash
$ find . -maxdepth 1 -name "*.txt" | sed s/.txt// | xargs -P8 -I% sh -c 'zip -r %.zip %.txt'

処理の解説ですが、
find . -maxdepth 1 -name "*.txt"
で今いるディレクトリ内でファイル名が".txt"で終わるファイルを検索し、その出力結果を
sed s/.txt//
に渡すことで、それぞれのファイル名から.txtという文字列を削除し、最後に
xargs -P8 -I% sh -c 'zip -r %.zip %.txt'
で渡されたファイル名を1つずつzipコマンドの引数に入れて処理をします。
findコマンドの-nameオプションで指定するファイル名は、同ディレクトリ内に他に.txtファイルが存在する場合は、"sample*"等に修正することで対応できますね。

2
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2