shellでプロジェクト内のテキストを一括置換する
- shell
素朴にやる
rg
と sed
を組み合わせれば実現できる。
$ rg FOO -l | xargs sed -i s/FOO/BAR/g
( ripgrepでgrep検索しつつsedで一括置換をかける | 7me を読みました、ありがとうございます)
素朴に関数化する
いちいちパイプでコマンド繋いで~パターン2回書いて~とやってられないので、こういう関数を .zshrc
などに書いておくと一応シュッと呼べる。
rp() {
rg $1 -l | xargs sed -i s/$1/$2/g
}
$ rp print println
# ... (特に何も出ない)
多少いい感じに関数化する
上記の例だと何も表示されないままスッ…と置換されて寂しいので、いい感じに経過・結果が分かるようにする。
あと、自分は絶対に引数を忘れて呼んだりマッチしないパターンを書いたりするので、それにも備えを打つ。
rp() {
if [ -z "$1" ] || [ -z "$2" ]; then
echo "USAGE: rp PATTERN REPLACEMENT"
else
MATCHED_FILES=`rg $1 -l`
FILES_COUNT=`echo $MATCHED_FILES | wc -l`
if [ -z "$MATCHED_FILES" ]; then
echo "No files matched."
fi
echo $MATCHED_FILES
while :
do
read "FLAG?$FILES_COUNT file(s) changed (y/n): "
if [ $FLAG = "y" ]; then
echo $MATCHED_FILES | xargs sed -i s/$1/$2/g
echo "success🦎"
break
elif [ $FLAG = "n" ]; then
echo "canceled"
break
else
echo "enter y or n."
fi
done
fi
}
$ rp print println
d.py
a.py
b.py
c.py
4 file(s) changed (y/n):
enter y or n.
4 file(s) changed (y/n): y
success🦎
やったね。
(シェルは本当に自信がないのでもっとマシな書き方を知っている方がいれば助けてください…)