🧊

Perlのワンライナーでテキストの一括置換

職場の諸先輩方の影響を受け、Terminal.appからiTerm2に乗り換えました。
コレ良い!ってなった点は、カラースキームがエクスポートできて、複数台で使いまわせる点と、範囲選択=クリップボードにコピーくらいですが・・。

というわけで、黒い画面でできることは黒い画面でやろう!のモットーの元、今回はPerlワンライナーを勉強します。

ワンライナー

プログラミング言語Perlですが、コマンドラインからも実行できます。

perl -e 'print "Hello One Liner!\n"'
# Hello One Liner!

みたいな感じです。
コマンドの引数として1行(OneLine)の短いスクリプトを書ける!ってやつなんですね。
それに、文字を置換する

s/hoge/fuga/g

のような正規表現の置換を組み合わせようという魂胆です。

やりたかったこと

ack -al 'nyan' | xargs perl -pi -e 's/nyan/PIYO/g'

"nyan"という文字列が含まれるファイル内の、"nyan"をすべて"PIYO"に置換します。
クラス名やプロパティの一括置換とかに使えます。

ファイル名がわかってる場合は、

perl -pi -e 's/nyan/PIYO/g' hoge.html

とかでも良いです。

xargs

しれっと書いてますが、先に実行したコマンドの結果を、その後につないだコマンドの引数にできるってやつです。
概念的には、

perl -pi -e 's/nyan/piyo/g' [fileName(s)]

このファイル名の引数の部分に、

ack -al 'nyan'

の結果を渡して実行することになります。
このackコマンドとlオプションでは、ファイル名のリストが返ってくるので、この使い方にはぴったりでした。

perlコマンドのオプションについて

今回の例において必要なオプションは以下の通り。

  • pをつけないと、出力結果が出ない=ファイルが変更されない
  • iをつけないと、出力結果がファイルに返らない(pのおかげで標準出力には出る
  • eをつけないと、文字がスクリプトとして認識されない(ワンライナーにならない
ack -al 'nyan' | xargs perl -pi -e 's/nyan/PIYO/g'

っていう今回のワンライナーですが、そもそも、

ack -al 'nyan' | xargs perl -pie 's/nyan/PIYO/g'

なんでこうできないの?って思いました。
オプションってひとまとめにできないもんかね?と。

でも、やってみると、

Can't open perl script "s/fuga/PIYO/g": No such file or directory

eオプションをつけずにperlコマンドを実行した場合、第一引数はスクリプトと解釈されるらしい。(付けたつもりやったけど
というわけで、オプションにも色々あって、独立して指定しないといけないオプションもいるんですね。

さらにちなみに、オプションの順番を変えてもダメです。eオプションの直後にスクリプト文字列!これが大事。

おわりに

厳密なパフォーマンス的な観点からいうと、xargsは使わない方が良いとも聞きます。
じゃあどうすれば良いのってのが今はわからないので、しばらくはコレでやってみようと思います。

ワンライナーのワくらいしか使えてない感はありますが、これできるだけでだいぶ楽なので良しとしますw
Perlって便利ですねー。