これは エキサイトホールディング アドベントカレンダー2022 の記事です。
概要
ふと、最新のPerlでワンライナーを書きたくなる時がありますよね?
ただ手元の環境のバージョンを上げるのは難しい。。。
そんな時にDockerさえあればDockerを使って最新のPerl環境を作って気軽にワンライナーが書けるよね。
という記事です。
前提・準備
<html>
<body>
<ul>
<li>ぴえん</li>
<li>ぴえんぴえん</li>
<li>泣きぴえん</li>
</ul>
</body>
</html>
- ぴえん → 🥺ぴえん🫶
- 泣きぴえん → 🥹泣きぴえん🫶
このようなindex.html
があるときに、上記のように文字列を置換したいとします。
まず最初に現状の表示を確かめるため上記のhtmlをブラウザで表示させてみましょう。
# index.htmlがあるのと同じディレクトリで実行します
# バックグラウンドでphpのビルドインサーバーを立ち上げます。エキサイトではphpがよく使われているので
# また、あとで止めやすいようにコンテナに名前を付けておきます
# せっかくなので2022/12/02時点で最新バージョンである8.2.0RC7を使います
docker run -d --name tmp-php-server -v $PWD:/app -w /app -p 8080:8080 --rm php:8.2.0RC7-alpine3.17 php -S 0.0.0.0:8080
localhost:8080 にアクセスして表示を見てみます。
では
下記のワンライナーで文字列を置換し、ファイルを書き換えてみます。
docker run -v $PWD:/app -w /app --rm perl:5.36.0-slim perl -i.bak -CSD -Mutf8 -ple 's/(?#あとで使うように名前付きでキャプチャしておきます)(?<普通ぴえん>(?#否定後読みで"泣き"が前にこない"ぴえん"を取ります)(?<!泣き)ぴえん)/\N{FACE WITH PLEADING EYES}$+{普通ぴえん}\N{HEART HANDS}/gx; s/(?<泣きぴえん>泣きぴえん)/\N{FACE HOLDING BACK TEARS}$+{泣きぴえん}\N{HEART HANDS}/gx' index.html
再度 localhost:8080 にアクセスして表示を見る。
上記ワンライナーの解説
-
docker run -v $PWD:/app -w /app --rm perl:5.36.0-slim
-
-v $PWD:/app
カレントディレクトリをコンテナ内の/app
にマウント -
-w /app
コンテナ内でのワーキングディレクトリを/app
に設定 -
--rm
コマンドが終了したときに自動でコンテナを削除するようにしておく
-
-
perl -i.bak -CSD -Mutf8 -ple
-
-i.bak
ファイルを置き換えする。元のファイルは.bak
の拡張子がついて取って置ける。 -
-CSD
標準入力・出力をUTF8として扱うようにするらしい -
-Mutf8
ソースコード内でUTF8を使うのでこの辺を付けとく -
-ple
ファイルをループして1行ずつ処理して$_
をprint
するワンライナーで良く付けるやつ
-
-
s/(?#あとで使うように名前付きでキャプチャしておきます)(?<普通ぴえん>(?#否定後読みで"泣き"が前にこない"ぴえん"を取ります)(?<!泣き)ぴえん)/\N{FACE WITH PLEADING EYES}$+{普通ぴえん}\N{HEART HANDS}/gx;
-
x
フラグを付けることで(?# ... )
で正規表現内にコメントを書けるので、何をしているか正規表現内にコメントしておきました。 -
\N{FACE WITH PLEADING EYES}
Perlではこのように\N{}
でUnicode名を指定することでその文字を書けるようです → このあたり -
$+{普通ぴえん}
名前付きでキャプチャした、マッチした部分を使用。
-
最後に
一応わざわざdocker run
を使ってワンライナーしてるのは
🥹 などの絵文字はUnicode 14で追加されたもので、Perl 5.36からUnicode 14に対応したため\N{FACE HOLDING BACK TEARS}
等の指定は5.36からでないと使用できません。(という合理的っぽい理由もあります…)
このように最新の環境を気軽に使用できるので、docker run
でワンライナーを書くのは便利ですね!
ちなみに、最後に終わったらphpのビルドインサーバーのコンテナを終了させておきます。
docker stop $(docker ps -f "name=tmp-php-server" -q)
検証環境
最後に検証した環境は以下。
Windows 10 WSL2 上のUbuntuです。
Dockerのバージョンは以下の通り。
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.5 LTS"
$ docker version
Client: Docker Engine - Community
Version: 20.10.21
API version: 1.41
Go version: go1.18.7
Git commit: baeda1f
Built: Tue Oct 25 18:02:21 2022
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.21
API version: 1.41 (minimum version 1.12)
Go version: go1.18.7
Git commit: 3056208
Built: Tue Oct 25 18:00:04 2022
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.9
GitCommit: 1c90a442489720eec95342e1789ee8a5e1b9536f
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
参考リンク