Zshメモ : zmvコマンドでリネーム(連番、ゼロ埋め、置換、拡張子、大文字、小文字など)
- zmvの使い方
- zmvのオプション
- zmvを使ったリネームのパターン
- 拡張子を変更する(a.txt -> a.csv)
- 拡張子を除去する(a.txt -> a)
- 先頭に文字を追加する(a.txt -> file_a.txt)
- 大文字化、小文字化する(AAA.txt -> aaa.txt)
- 先頭だけ大文字化する(file.txt -> File.txt)
- 連番を付与する(a.txt, b.txt -> a-1.txt, b-2.txt)
- ファイル名に数値を加算する(pic1.jpg -> pic2.jpg)
- ゼロ埋めする(pic1.jpg -> pic0001.jpg)
- ゼロ埋めした連番を付与する(a.txt, b.txt -> a-0001.txt, b-0002.txt)
- ゼロを除去する(pic0001.jpg -> pic1.jpg)
- 数値の範囲を指定してリネームする
- ファイル名のスペースを置換する(a a.txt -> a_a.txt)
- 特定の文字を置換する(pic1.jpg -> file1.jpg)
- 特定の文字を除去する(pic1.jpg -> 1.jpg)
- 最初の数文字を取り除く(0001_a.txt -> a.txt)
- 文字列を入れ替える(file-1.txt -> 1-file.txt)
- サブディレクトリも処理する
zmvの使い方
Zshのzmv
というコマンドを使うと、いろいろなリネームが簡単にできるので便利。
zmv
コマンドを使うためにはautoloadが必要なので、下記行を.zshrc
に追加しておく。
autoload -U zmv
簡単な使い方はzmv
とコマンドを打ってリターンすると確認できる。マニュアルについてはman zshcontrib
の中に書いてある。
$ zmv Usage: zmv [OPTIONS] oldpattern newpattern where oldpattern contains parenthesis surrounding patterns which will be replaced in turn by $1, $2, ... in newpattern. For example, zmv '(*).lis' '$1.txt' renames 'foo.lis' to 'foo.txt', 'my.old.stuff.lis' to 'my.old.stuff.txt', and so on. Something simpler (for basic commands) is the -W option: zmv -W '*.lis' '*.txt' This does the same thing as the first command, but with automatic conversion of the wildcards into the appropriate syntax. If you combine this with noglob, you don't even need to quote the arguments. For example, alias mmv='noglob zmv -W' mmv *.c.orig orig/*.c
例に書いてあるように
$ zmv -W '*.lis' '*.txt'
を実行すると拡張子を.lis
から.txt
に変更できる(このくらいならrename
コマンドでもできるが)。
zmvのオプション
マニュアルには下記オプションの説明が書いてあるが、よく使いそうなものを見てみる。
zmv [ -finqQsvwW ] [ -C | -L | -M | -{p|P} program ] [ -o optstring ]
-n : 実行せずに変更内容を確認する
-n
オプションはNo excecution
という意味で、変更内容は表示するが実際には実行しない。操作に慣れないうちはこのオプションで確認してから実行するのがよさそう。
$ zmv -nW '*.txt' '*.csv' mv -- a.txt a.csv mv -- b.txt b.csv
-W : ワイルドカードの扱いを簡単にする
通常の使い方では対象とするパターンのワイルドカード部分を()
で囲む必要があり、()
で囲んだものを参照する場合は順番に$1
、$2
とする。下記例の場合、$1
には-
より前のfile
、$2
には-
より後のa
またはb
が入る。
$ zmv -n '(*)-(*).txt' '$1_$2.csv' mv -- file-a.txt file_a.csv mv -- file-b.txt file_b.csv
-W
オプションを指定すると変換元(左側)のワイルドカードには括弧がついているとみなされ、変換先(右側)のワイルドカードは順番に$1
、$2
とみなされるので、上記と同じ操作が以下のように簡単に書ける。
$ zmv -nW '*-*.txt' '*_*.csv' mv -- file-a.txt file_a.csv mv -- file-b.txt file_b.csv
なお、noglob
を指定すればシングルクォーテーションも不要になりさらに簡単に書ける。
$ noglob zmv -nW *-*.txt *_*.csv mv -- file-a.txt file_a.csv mv -- file-b.txt file_b.csv
毎回このオプションを指定するのも大変なのでエイリアスを設定しておくとよい。
$ alias mmv='noglob zmv -W' $ mmv -n *-*.txt *_*.csv mv -- file-a.txt file_a.csv mv -- file-b.txt file_b.csv
-f : ファイルが存在しても上書きする
リネーム先のファイルが存在する場合はエラーになるが、
$ zmv -nW '*.txt' '*.csv' zmv: error(s) in substitution: file exists: a.csv
-f
オプションを指定すれば上書きできるようになる。
$ zmv -nWf '*.txt' '*.csv' mv -- a.txt a.csv mv -- b.txt b.csv
-C : コピーする
zmv
という名前の通り、デフォルトではmv
の操作をするが、cp
したい場合はC
オプションを指定する。
$ zmv -nWC '*.txt' '*.csv' cp -- a.txt a.csv cp -- b.txt b.csv
-Ls : シンボリックリンクを作成する
シンボリックリンクを作成する場合は-Ls
を指定する。-L
はln
コマンドを実行するということなので、-L
だけだとハードリンクになる。
$ zmv -WLs '*.txt' '*.csv' $ ls -l 合計 0 lrwxrwxrwx 1 vagrant vagrant 5 2月 25 21:00 a.csv -> a.txt -rw-r--r-- 1 vagrant vagrant 0 2月 25 20:55 a.txt lrwxrwxrwx 1 vagrant vagrant 5 2月 25 21:00 b.csv -> b.txt -rw-r--r-- 1 vagrant vagrant 0 2月 25 20:55 b.txt
以下のようにdotfilesにシンボリックリンクを作成する場合に使えそう。
$ zmv -WLs 'username/dotfiles/dot.*' '.*'
zmvを使ったリネームのパターン
zmvを使ったリネームのパターンをZSH-LOVERSなどを参考に調べてみる。リネームの動作がわかるように-n
オプションを指定しているが、実際にリネームする場合は-n
は不要。
拡張子を変更する(a.txt -> a.csv)
-W
オプションの説明で書いた通り。
$ zmv -nW '*.txt' '*.csv' mv -- a.txt a.csv mv -- b.txt b.csv
拡張子を除去する(a.txt -> a)
変換先の拡張子を書かなければよい。
$ zmv -nW '*.txt' '*' mv -- a.txt a mv -- b.txt b
先頭に文字を追加する(a.txt -> file_a.txt)
変換先の先頭に文字を追加すればよい。
$ zmv -nW '*.txt' 'file_*.txt' mv -- a.txt file_a.txt mv -- b.txt file_b.txt
大文字化、小文字化する(AAA.txt -> aaa.txt)
大文字化、小文字化する場合はU
、L
といった変数展開フラグを使用する。
$ zmv -n '(*)' '${(U)1}' mv -- AAA.txt AAA.TXT mv -- BbB.txt BBB.TXT mv -- CCc.TXT CCC.TXT
$ zmv -n '(*)' '${(L)1}' mv -- AAA.txt aaa.txt mv -- BbB.txt bbb.txt mv -- CCc.TXT ccc.txt
先頭だけ大文字化する(file.txt -> File.txt)
先頭だけ大文字化したい場合はC
を使用すればよい。
$ zmv -n '(*).txt' '${(C)1}.txt' mv -- file.txt File.txt
連番を付与する(a.txt, b.txt -> a-1.txt, b-2.txt)
連番を付与する場合は以下のようにする。
$ c=1 zmv -n '*.txt' '$((c++)).txt' mv -- a.txt 1.txt mv -- b.txt 2.txt mv -- c.txt 3.txt
初期値と加算値も変更可能。
$ c=3 zmv -n '*.txt' '$((c=c+2)).txt' mv -- a.txt 5.txt mv -- b.txt 7.txt mv -- c.txt 9.txt
元のファイル名を残す場合。
$ c=1 zmv -n '(*).txt' '$1-$((c++)).txt' mv -- a.txt a-1.txt mv -- b.txt b-2.txt mv -- c.txt c-3.txt
ファイル名に数値を加算する(pic1.jpg -> pic2.jpg)
連番の場合は数値の大きい方からリネームする必要があるので(On)
によりファイル名の降順でソートする。(On)
などのGlob Qualifiersを使う場合は-Q
の指定が必要。また、ファイル名が連番の場合は-f
が必要となる。
$ zmv -fQn 'pic([0-9]##).jpg(On)' 'pic$(($1 + 1)).jpg' mv -- pic3.jpg pic4.jpg mv -- pic2.jpg pic3.jpg mv -- pic1.jpg pic2.jpg
(On)
を指定しないと若い番号からリネームし、pic4.jpg
だけが残ることになるので注意。
$ zmv -fQn 'pic([0-9]##).jpg' 'pic$(($1 + 1)).jpg' mv -- pic1.jpg pic2.jpg mv -- pic2.jpg pic3.jpg mv -- pic3.jpg pic4.jpg
ゼロ埋めする(pic1.jpg -> pic0001.jpg)
数値をゼロ埋めする場合。桁数や埋める文字も変更可能。
$ zmv -n 'pic(*).jpg' 'pic${(l:4::0:)1}.jpg' mv -- pic1.jpg pic0001.jpg mv -- pic2.jpg pic0002.jpg mv -- pic3.jpg pic0003.jpg
$ zmv -n 'pic(*).jpg' 'pic${(l:7::_:)1}.jpg' mv -- pic1.jpg pic______1.jpg mv -- pic2.jpg pic______2.jpg mv -- pic3.jpg pic______3.jpg
ゼロ埋めした連番を付与する(a.txt, b.txt -> a-0001.txt, b-0002.txt)
連番とゼロ埋めの組み合わせ。
c=1 zmv -n '(*).txt' '$1-${(l:4::0:)$((c++))}.txt' mv -- a.txt a-0001.txt mv -- b.txt b-0002.txt mv -- c.txt c-0003.txt
ゼロを除去する(pic0001.jpg -> pic1.jpg)
セロを除去したい場合は以下のようにする。##
は最長マッチ。
$ zmv -n '(pic)0##(?*)' '$1$2' mv -- pic0001.jpg pic1.jpg mv -- pic0002.jpg pic2.jpg mv -- pic0003.jpg pic3.jpg mv -- pic0010.jpg pic10.jpg mv -- pic0100.jpg pic100.jpg
数値の範囲を指定してリネームする
数値の範囲を指定したい場合は<1->
のように指定する。<1->
は1以上の場合。
$ zmv -n 'pic(<1->).jpg' 'pic${(l:4::0:)1}.jpg' mv -- pic1.jpg pic0001.jpg mv -- pic2.jpg pic0002.jpg mv -- pic3.jpg pic0003.jpg mv -- pic4.jpg pic0004.jpg mv -- pic5.jpg pic0005.jpg
2以下の場合。
$ zmv -n 'pic(<-2>).jpg' 'pic${(l:4::0:)1}.jpg' mv -- pic1.jpg pic0001.jpg mv -- pic2.jpg pic0002.jpg
3以上4以下の場合。
$ zmv -n 'pic(<3-4>).jpg' 'pic${(l:4::0:)1}.jpg' mv -- pic3.jpg pic0003.jpg mv -- pic4.jpg pic0004.jpg
ファイル名のスペースを置換する(a a.txt -> a_a.txt)
置換する場合は${1//パターン/置換後文字列}
を使用する。
$ zmv -n '(*)' '${1// /_}' mv -- 'a a.txt' a_a.txt mv -- 'b b.txt' b__b.txt mv -- 'c c c.txt' c_c__c.txt
複数のスペースを1つにまとめたい場合は##
で最長マッチにする。
$ zmv -n '(*)' '${1// ##/_}' mv -- 'a a.txt' a_a.txt mv -- 'b b.txt' b_b.txt mv -- 'c c c.txt' c_c_c.txt
特定の文字を置換する(pic1.jpg -> file1.jpg)
スペースを置換する方法と同じ。
$ zmv -n '(*)' '${1//pic/file}' mv -- pic1.jpg file1.jpg mv -- pic2pic.jpg file2file.jpg
特定の文字を除去する(pic1.jpg -> 1.jpg)
置換後文字列をなくせば除去される。
$ zmv -n '(*)' '${1//pic/}' mv -- pic1.jpg 1.jpg mv -- pic2pic.jpg 2.jpg
最初の数文字を取り除く(0001_a.txt -> a.txt)
ファイル名の最初の4文字を取り除く場合は$f[5,-1]
とする。
$ zmv -n '*' '$f[5,-1]' mv -- 001_a.txt a.txt mv -- 002_b.txt b.txt mv -- 003_c.txt c.txt
文字列を入れ替える(file-1.txt -> 1-file.txt)
$1
と$2
を入れ替えるなどすればよい。このような入れ替えの場合は-W
オプションは使えない。
$ zmv -n '(*)-(*).txt' '$2-$1.txt' mv -- file-1.txt 1-file.txt mv -- file-2.txt 2-file.txt
サブディレクトリも処理する
サブディレクトリも再帰的に処理したい場合は以下のようにする。$1
にはフルパスが入る。
$ zmv -n '(**/)(*).txt' '$1$2.csv' mv -- dir1/dir1-1/b.txt dir1/dir1-1/b.csv mv -- dir1/dir1-2/c.txt dir1/dir1-2/c.csv mv -- dir1/a.txt dir1/a.csv mv -- dir2/dir2-1/e.txt dir2/dir2-1/e.csv mv -- dir2/d.txt dir2/d.csv
簡潔に書くことも可能。
$ noglob zmv -nW **/*.txt **/*.csv
mv -- dir1/dir1-1/b.txt dir1/dir1-1/b.csv
mv -- dir1/dir1-2/c.txt dir1/dir1-2/c.csv
mv -- dir1/a.txt dir1/a.csv
mv -- dir2/dir2-1/e.txt dir2/dir2-1/e.csv
mv -- dir2/d.txt dir2/d.csv
- 作者: DrewNeil,新丈径
- 出版社/メーカー: KADOKAWA / アスキー・メディアワークス
- 発売日: 2014/01/28
- メディア: Kindle版
- この商品を含むブログ (4件) を見る