変数を含む Perl のワンライナーを alias に登録する方法(csh)


変数を使った Perl のワンライナーを alias 登録する時に、変数がシェル変数として解釈されてしまうのを回避する方法。

変数を使った Perl のワンライナーの例

例えば、「拡張子が大文字のファイルがあったら小文字に変更する」という処理をするための Perl のワンライナーは以下のようになる。

find . -type f | perl -n -e ‘chomp; m/\.[0-9A-Z]+\Z/ and $target=$_ and $target=~s/([0-9A-Z]+)\Z/lc($1)/e and rename ($_, $target)’

これを alias に登録しておきたい場合、以下のように指定してしまうと変数 $target がシェル変数として解釈されてしまい、エラーになる。

変数を使用している Perl ワンライナーを alias 登録しようとした時に出るエラー

% alias extlc “find . -type f | perl -n -e ‘chomp; m/\.[0-9A-Z]+\Z/ and $target=$_ and $target=~s/([0-9A-Z]+)\Z/lc($1)/e and rename ($_, $target)'”
target: 定義されていない変数です.

また、Perl の変数のつもりで「$_」を使うとこれが先にシェル変数として展開されてしまい、「” が対応しません.」というエラーが出る。

$_ を使用している Perl ワンライナーを alias 登録しようとした時に出るエラー

% alias largeimages “find . -type f | perl -n -e ‘chomp; m/\.png\Z/i and -s $_ > 1024*10**3 and print qq{$_\n}'”
” が対応しません.

また、正規表現にマッチした文字列を参照するための特殊変数 $1、$2、… も、先にシェル変数として展開されてしまうのでうまく行かない。

alias 登録時のエラー回避の方法(csh)

このような時は、alias 指定のコマンド部分を分割し、Perl の変数を含む部分をシングルクオートで囲う。

alias extlc “find . -type f | perl -n -e ‘chomp; m/\.[0-9A-Z]+\Z/ and ” ‘$target=$_ and $target=~s/([0-9A-Z]+)\Z/lc($1)/e and rename ($_, $target)’ “‘”

理屈の補足

csh の場合は、コマンドのチャンクを区切ってアペンドして行けるので、次のように書ける。一つのチャンク内でカッコの整合性が取れていなくても、全体として整っていればOK。

alias commandname “CHUNK1” ‘CHUNK2’ “CHUNK3” …

sh、bash の場合は…多分シェルプログラムを書くのが正解と思われます。