Shift-JISファイルをgrepする方法
背景
古い日本語のWebサイトや、レガシーなWindowsアプリケーションのソースコードなどでは、Shift_JISエンコーディングが使用されていることが多い。
VS Codeなどのエディタで検索しても、UTF-8で検索してしまうため、Shift_JISのファイルをgrepできない。IntelliJ IDEAなどのIDEであれば、Shift_JISのファイルを検索できるが、そういった環境がない場合は、grepコマンドを使ってShift_JISのファイルを検索する方法があると便利である。
ただし、grepコマンドはデフォルトではShift_JISのファイルを扱うことができないため、Shift_JISのファイルをgrepするためには事前に準備が必要になる。
方法
環境
- macOS
基本準備
まず、Shift_JISのファイルをUTF-8に変換する必要がある。Homebrew経由でnkf
コマンドをインストールする。
brew install nkf
Shift_JISファイルに対しての検索方法だが、nkf
コマンドを使って対象ファイルをUTF-8に変換した後、grep
コマンドで検索する。
nkf -w <file> | grep "keyword"
これでShift_JISのファイルをgrepできた。
応用
対象ファイルが1つならば、上記の方法で十分だが複数ファイルがある場合だと一括で検索をしたい。
その場合は、以下のようにfor文を使って一括検索を行う。対象ファイルが複数のため、ファイルパスも表示するようにしている。
for file in <file>; do
nkf -w "$file" | grep --with-filename -H "keyword" | sed "s|^|$file: |"
done
--with-filename (-H)
: ファイル名を表示するsed "s|^|$file: |"
: ファイル名を各行の先頭に付加する
これで複数のShift_JISのファイルを一括でgrepできた。
Alias化
毎回上記のコマンドを打つのは面倒なため、Alias化しておくと便利である。
スクリプトの用意
まず以下のコードを適当な場所に追加する。今回は~/bin/sjis-grep.sh
などに保存しておくことにする。
#!/bin/bash
sgrep() {
# 引数チェック
if [ $# -lt 2 ]; then # 引数が2つ未満の場合はエラー
echo "Usage: sgrep PATTERN FILE_PATTERN"
echo "Example: sgrep '検索文字列' './**/*.html'"
return 1
fi
local search_pattern="$1"
local file_pattern="$2"
# 複数のファイルパターンのサポート
shift 2 # 最初の2つの引数(検索パターンとファイルパターン)を削除
# 追加のパターンが提供されている場合、それらを追加する
if [ $# -gt 0 ]; then # 追加の引数がある場合
file_pattern="$file_pattern $@"
fi
# ファイルパターンを評価し、各ファイルを処理する
for file in $(eval echo $file_pattern); do
if [ -f "$file" ]; then
# UTF-8に変換してgrepし、マッチした行の前にファイル名を付ける
nkf -w "$file" | grep --with-filename -H "$search_pattern" | sed "s|^|$file: |"
fi
done
}
sgrep
コマンドという名前にしておく。
rcファイルへの追加
次に、~/.bashrc
や ~/.zshrc
などに以下のコードを追加する。
source ~/bin/sjis-grep.sh
~/.bashrc
や ~/.zshrc
に直接スクリプトを定義してもよいが長くなるため別ファイルとした。
再読み込み
これで、sgrep
コマンドを使ってShift_JISのファイルをgrepできるようになった。再読み込みを行えば以下が実行できるようになる。
sgrep "keyword" "./**/*.html"
パスは複数指定もできるため、sgrep "keyword" "./pc/**/*.html" "./sp/**/*.html"
みたいな形で異なったディレクトリも一括で検索も可能である。