Shift-JISファイルをgrepする方法

5 min read

背景

古い日本語の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"みたいな形で異なったディレクトリも一括で検索も可能である。