ZSH-LOVERSメモ(7) : ZMVを使った一括リネームのパターン
ZSH-LOVERS(1)というZshのTipsを紹介しているページがあるので見てみる(続き)。
7番目はZMVコマンドで複数ファイルのリネームが簡単にできる。詳細についてはman zshcontrib
に記述されている。
ZMVコマンドを使うためにはautoloadが必要。
autoload -U zmv
簡単な使い方はzmv
とコマンドを打ってリターンすると確認できる。
$ 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
直感的に使うにはnoglob zmv -W
とすればよい。
いきなり実行するのは怖いのでその場合は-n
オプションを指定すれば、実際には実行せずに対象となるファイルを確認できる。
$ noglob zmv -W -n *.txt *.csv ⏎ mv -- a.txt a.csv mv -- b.txt b.csv
簡単な使い方はわかったのでZSH-LOVERSの内容を見てみる。ちゃんと理解できるまでは-n
オプションを付けで事前に確認した方がよさそう。
# Remove illegal characters in a fat32 file system. Illegal characters are # / : ; * ? " < > | # NOTE: ``-Q'' and (D) is to include hidden files. $ unwanted='[:;*?\"<>|]' $ zmv -Q "(**/)(*$~unwanted*)(D)" '$1${2//$~unwanted/}'
上記の例はunwanted
で指定した記号を取り除く。
# Changing part of a filename (i. e. "file-hell.name" -> "file-heaven.name") $ zmv '(*)hell(*)' '${1}heaven${2}' # or $ zmv '*' '$f:s/hell/heaven/'
ファイル名の一部を置換。:s
は編集子。
# remove round bracket within filenames # i. e. foo-(bar).avi -> foo-bar.avi $ zmv '*' '${f//[()]/}'
丸カッコを取り除く。
# serially all files (foo.foo > 1.foo, fnord.foo > 2.foo, ..) $ autoload zmv $ ls * 1.c asd.foo bla.foo fnord.foo foo.fnord foo.foo $ c=1 zmv '*.foo' '$((c++)).foo' $ ls * 1.c 1.foo 2.foo 3.foo 4.foo foo.fnord
連番でリネーム。
# Rename "file.with.many.dots.txt" by substituting dots (exept for the last # one!) with a space $ touch {1..20}-file.with.many.dots.txt $ zmv '(*.*)(.*)' '${1//./ }$2'
拡張子が連続しているファイルの一番最後の拡張子のみ残してリネーム。上記の例の場合、1-file.with.many.dots.txt
は1-file with many dots.txt
になる。
# Remove the first 4 chars from a filename $ zmv -n '*' '$f[5,-1]' # NOTE: The "5" is NOT a mistake in writing!
最初の4文字を取り除く。
# Rename names of all files under the current Dir to lower case, but keep # dirnames as-is. $ zmv -Qv '(**/)(*)(.D)' '$1${(L)2}'
カレントディレクトリ以下のファイル名を小文字にする。ディレクトリ名はそのまま。
# replace all 4th character, which is "1", with "2" and so on $ autoload -U zmv $ zmv '(???)1(???[1-4].txt)' '${1}2${2}'
4番目の文字を変更したい場合など。上記の例の場合00010001.txt
は00020001.txt
になる。
# Remove the first 15 characters from a string $ touch 111111111111111{a-z} $ autoload zmv $ zmv '*' '$f[16,-1]'
最初の15文字を取り除く(4文字を取り除く例と同じ)。
# Replace spaces (any number of them) with a single dash in file names $ autload zmv $ zmv -n '(**/)(* *)' '$1${2//( #-## #| ##)/-}' # or - with Bash $ find . -depth -name '* *' -exec bash -c ' > shopt -s extglob > file=$1 > dir=${file%/*} > name=${file##*/} > newname=${name//*([ -]) *([ -])/-} > mv -i -- "$file" "$Dir/$newname"' {} {} \;
空白を-
に置換。
# Clean up file names and remove special characters $ autoload zmv $ zmv -n '(**/)(*)' '$1${2//[^A-Za-z0-9._]/_}'
A-Za-z0-9._
以外の文字を_
に置換。
# Add *.py to a bunch of python scripts in a directory (some of them end # in *.py and give them all a proper extension $ autoload zmv $ zmv -n '(**/)(con*)(#qe,file $REPLY | grep "python script",)' '$1$2.py'
特定ディレクトリ内(con*
ディレクトリ以下のpython script
ディレクトリ内?)のファイルに.py
を追加。
# lowercase all extensions (i. e. *.JPG) incl. subfolders $ autoload zmv $ zmv '(**/)(*).(#i)jpg' '$1$2.jpg' # Or - without Zsh $ find Dir -name '*.[jJ][pP][gG]' -print | while read f > do > case $f in > *.jpg) ; > *) mv "$f" "${f%.*}.jpg" ; > esac > done
大文字の拡張子を小文字にする。上記の例は*.JPG
を*.jpg
にする。
# remove leading zeros from file extension $ autoload zmv $ ls filename.001 filename.003 filename.005 filename.007 filename.009 filename.002 filename.004 filename.006 filename.008 filename.010 $ zmv '(filename.)0##(?*)' '$1$2' $ ls filename.1 filename.10 filename.2 filename.3 filename.4 filename.5 ..
ファイル名のゼロを取り除く。
# renumber files. $ autoload zmv $ ls * foo_10.jpg foo_2.jpg foo_3.jpg foo_4.jpg foo_5.jpg foo_6.jpg .. $ zmv -fQ 'foo_(<0->).jpg(.nOn)' 'foo_$(($1 + 1)).jpg' $ ls * foo_10.jpg foo_11.jpg foo_3.jpg foo_4.jpg foo_5.jpg ...
ファイル名に数値を加算。
# adding leading zeros to a filename (1.jpg -> 001.jpg, .. $ autoload zmv $ zmv '(<1->).jpg' '${(l:3::0:)1}.jpg'
ゼロ埋めでリネーム。<1->
は1以上という表現。<1-10>
とすれば1から10の間。
# See above, but now only files with a filename >= 30 chars $ autoload zmv $ c=1 zmv "${(l:30-4::?:)}*.foo" '$((c++)).foo'
ファイル名が30文字以上のファイルを1.foo
、2.foo
のようにリネーム。
# Replace spaces in filenames with a underline $ autoload zmv $ zmv '* *' '$f:gs/ /_'
空白を_
に置換。:gs
は編集子(Modifiers)。
# Change the suffix from *.sh to *.pl $ autoload zmv $ zmv -W '*.sh' '*.pl'
拡張子を変更する。
# Add a "".txt" extension to all the files within ${HOME} # ``-.'' is to only rename regular files or symlinks to regular files, # ``D'' is to also rename hidden files (dotfiles)) $ autoload zmv $ zmv -Q '/home/**/*(D-.)' '$f.txt' # Or to only rename files that don't have an extension: $ zmv -Q '/home/**/^?*.*(D-.)' '$f.txt'
${HOME}
以下のファイルに.txt
を追加。
最後のコマンドは拡張子がないファイルのみを対象。
# Recursively change filenames with characters ? [ ] / = + < > ; : " , - * $ autoload zmv $ chars='[][?=+<>;",*-]' $ zmv '(**/)(*)' '$1${2//$~chars/%}'
上記の例はchars
で指定した記号を%
に置換。
# Removing single quote from filenames (recursively) $ autoload zmv $ zmv -Q "(**/)(*'*)(D)" "\$1\${2//'/}"
シングルクオートを取り除く。
# When a new file arrives (named file.txt) rename all files in order to # get (e. g. file119.txt becomes file120.txt, file118.txt becomes # file119.txt and so on ending with file.txt becoming file1.txt $ autoload zmv $ zmv -fQ 'file([0-9]##).txt(On)' 'file$(($1 + 1)).txt'
file119.txt
をfile120.txt
のようにファイル名に数値を加算してリネームしたい場合。-f
はforceオプションなのでファイルが存在すれば上書きされる。
# lowercase/uppercase all files/directories $ autoload zmv $ zmv '(*)' '${(L)1}' # lowercase $ zmv '(*)' '${(U)1}' # uppercase
小文字化。大文字化。(L)
と(U)
はParameter Expansion Flagsというもの。
# Remove the suffix *.c from all C-Files $ autoload zmv $ zmv '(*).c' '$1'
拡張子を取り除く。
# Uppercase only the first letter of all *.mp3 - files $ autoload zmv $ zmv '([a-z])(*).mp3' '${(C)1}$2.mp3'
1文字目のみ大文字にする。(C)
はParameter Expansion Flagsというものでキャピタライズできる。
# Copy the target `README' in same directory as each `Makefile' $ autoload zmv $ zmv -C '(**/)Makefile' '${1}README'
-C
を指定するとmv
ではなくcp
ができる。上記の場合はMakefile
があるディレクトリにREADME
というファイル名でコピーされる。
# Removing single quote from filenames (recursively) $ autoload zmv $ zmv -Q "(**/)(*'*)(D)" "\$1\${2//'/}"
シングルクオートを取り除く(2回目...)。
# Rename pic1.jpg, pic2.jpg, .. to pic0001.jpg, pic0002.jpg, .. $ autoload zmv $ zmv 'pic(*).jpg' 'pic${(l:4::0:)1}.jpg' $ zmv '(**/)pic(*).jpg' '$1/pic${(l:4::0:)2}.jpg' # recursively
ゼロ埋めでリネーム。