Info.plistの数値のvalueをインクリメントするワンライナー

ありえんほど疲れた。egrep何も分からん。結局分からんくて使わずに書いた。

モチベーション

Info.plistの数値のvalueをインクリメントするワンライナーを書きたい。

題材として、個人開発しているSwiftUIアプリのInfo.plistを改造して試してみる。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSHealthShareUsageDescription</key>
    <string>Get a bike workout.</string>
    <key>HogeBuildVersion</key>
    <string>156</string>  // インクリメントしたい!
</dict>
</plist>

上記の HogeBuildVersionvalueの156をインクリメントするシェルスクリプトを書く。

コード

ワンライナー

$ plutil -extract HogeBuildVersion xml1 -o - ./Info.plist |  sed -n "s/<string>\(.*\)<\/string>/\1/p" | awk '{print $0+1}' | xargs -I NUM plutil -replace HogeBuildVersion -string NUM ./Info.plist 

見やすく改行したver.

$ plutil -extract HogeBuildVersion xml1 -o - ./Info.plist |
sed -n "s/<string>\(.*\)<\/string>/\1/p" |
awk '{print $0+1}' |
xargs -I NUM plutil -replace HogeBuildVersion -string NUM ./Info.plist

分解して解説

1: plutil -extract HogeBuildVersion xml1 -o - ./Info.plist |
2: sed -n "s/<string>\(.*\)<\/string>/\1/p" |
3: awk '{print $0+1}' |
4: xargs -I NUM plutil -replace HogeBuildVersion -string NUM ./Info.plist

1. plutil

1: plutil -extract HogeBuildVersion xml1 -o - ./Info.plist -n

plutil は .plist ファイルをいい感じに処理できるコマンド。
key HogeBuildVersionvalueをstdoutする。plistタグより上の内容もstdoutされてしまうので2以降でトリミングしていく。

$ plutil -extract HogeBuildVersion xml1 -o - ./Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>156</string>
</plist>

2. sed

2: sed -n "s/<string>\(.*\)<\/string>/\1/p"

ここに一番時間割いた。sedが一番理解しやすかった気がする。
-n で引っかかった行のみ出力。

s/BEFORE/AFTER/p としたときに、BEFORE内で \(\)で囲んだものを AFTER 内で \1 として利用できる。あとはスラッシュのエスケープシーケンスで見づらくなっているだけ。 末尾の p-n と併用することで結果を出力するために記述。

3. awk

3: awk '{print $0+1}'

パイプで受け取った値をインクリメント。

4. xargs + plutil

4: xargs -I NUM plutil -replace HogeBuildVersion -string NUM ./Info.plist

xargs -I {VAR} でパイプで受け取った値を変数らしきものに入れることができる。後方で使用可能。(処理的にはreplaceしているっぽい?)

plutil で指定したkeyのvalueを更新。

参考