目的
正規表現を使ってカレントディレクトリ内のすべてのファイルとディレクトリを一度にリネームするコマンドregmv
を作る。
おまけとしてワンライナー版も紹介する。
コマンドの使い方
perlの正規表現を引数に渡す。
(実際には正規表現以外にもperlとして解釈できる文字列であれば何でも動く)
使用例
ディレクトリ内にa.txt
, b.txt
, ab.txt
がある状態でregmv s/b/c/
とするとa.txt
, c.txt
, ac.txt
になる。
オプション
-
-t
,--test
: 実行されるコマンドだけ表示して実際にはリネームしない -
-v
,--verbose
: リネームの様子を出力する
方法
function regmv () {
local -A opthash # オプション格納用のopthashという連想配列を作成
# zparseoptsを使って[-t, --test, -v, --verbose]のオプションを受け取るように設定
zparseopts -D -E -A opthash -- t -test v -verbose
# [-v, --verbose]のどちらかがついていればmvに -v オプションを付加
local mvopt=''
if [[ -n "${opthash[(i)-v]}" ]] || [[ -n "${opthash[(i)--verbose]}" ]]; then
local mvopt='-v'
fi
# [-t, --test]のどちらかがついていればテストモードに以降 (実行されるコマンドだけ表示して実際にはリネームしない)
local act='print `mv '$mvopt' "$x" "$_" `'
if [[ -n "${opthash[(i)-t]}" ]] || [[ -n "${opthash[(i)--test]}" ]]; then
local act='print "mv $x $_\n"'
fi
rescmd='chomp; $x = $_; '$1'; '$act' if $_ ne $x' # perlで実行。 正規表現で名前が変わらないやつはスキップ
ls | perl -ne $rescmd
}
課題・今後の展望
- 正規表現を引数として渡すことを想定しているが、実際にはなんでも動くので危ない
- 正規表現を明示的に指定するオプションをつけてあげたい (現在は登録されていない引数の内一番最初に出てくるやつ)
- ファイル(or ディレクトリ)だけリネームするようなオプションが欲しい
- リネーム対象を変更するオプションが欲しい (現在はカレントディレクトリ内のすべて)
下2つはls
の部分をちょこちょこっと変えればできるけど面倒なのでだれかやってくれないかな。。。
おまけ: ワンライナー版
zshのコマンド定義するとか面倒で今だけやりたいって人向け。
-t
や-v
のオプションはなくなるけどコピペで今すぐ動く。
ls | perl -ne 'chomp; $x = $_; s/これを/これに置換する/g; `mv "$x" "$_"` if $_ ne $x'
参考文献
- zshで簡単にコマンドライン オプションを解析する
- zshmodules(1) - Linux man page (zparseoptsの説明)