perl のワンライナーに関しての、適当な解説 #1/#2/#3/#4
rename.pl(リンク先はググって一番上に来たサイト)
ワンライナー化
わざわざスクリプトにしてディレクトリを汚す事も無い。
.bashrc
function rename() { perl -le '$a = shift; for(@ARGV){ $b = $_ ; eval $a; die $@ if $@; rename $b, $_ if $b ne $_ ; }' -- "$@" ;}
-
$a
はもちろん準予約語。私はワンライナー以外で、こんな使い方はしません。
使い方
当然、source ~/.bashrc
した後に、
第一引数に perl のコード。
以降の引数にファイル名
$ rename '$_ = "${_}.bak"' *
とか、
$ rename 's/foo/bar/' *
とか。
注意点
- 置換文字列に
/
や、:
を含めない - ファイル名も
*
とか含めない
等々、
まあ、後は常識的範囲で。
以下のコードも同じ扱い。
で、ついでに中身も変更したい。
てことで昔作ったの。
上記コードに組込むことは出来るけど、長くなるから。
まず、
中身変更用ワンライナー
.bashrc
function subst() { perl -i -pe 'BEGIN{ $a = shift ; } next if ! -T $ARGV ; eval $a' -- "$@" ; }
# 本当は、replace
って名前にしようかと思ったら、MySQL の付随コマンドが使ってました。
next if ! -T $ARGV
がどうにも不恰好だけど、バイナリの中身を下手に改変する可能性が残るくらいなら、、、
使い方は、上と同様で、
$ rename 's/foo/bar/g' *
ってすれば、ファイル中の foo が bar になる、と。
もちろん引数を与える時にファイルだけを与える事。
一括変換
で指定ファイルの一括置換
.bashrc
function renamef() { subst "$@" ; rename "$@" ;}
って事で、単に纏めただけ。使い方も変更無し。
根刮ぎ変換
更に、カレントディレクトリ以下のファイルの内容と名前を根刮ぎ変換してしまおうと。
.bashrc
function relump(){
subst $1 $(find . -type f)
rename $1 $(find . | perl -F'/' -Mvars=@a -lane 'push @a, [ $_, @F ] }{ print $_->[0] for sort { @{$b} <=> @{$a} } @a ')
}
- subst の方は、 find の出力結果を素直に与えればいい。
- rename の方は、
-
./foo/foo.txt
の様な場合に、確実に深いディレクトリからのリネームにさせる為に、階層降順ソートワンライナーをカマしてある。 - シンボリックリンクの除外などしていない
-
使い方
$ cd PROJECT
$ relump 's/foo/bar/g'
これは、コード以外の引数を取りません。
利便性を考えたら、カレント以外のディレクトリも指定できる形式にしても良かったかと思うが、そこまで必要性が無かった。たまーに打つだけだし。