search
LoginSignup
16

posted at

updated at

シェルスクリプトでエクセルファイルを全文検索してみる

概要

特定の文字列を含むエクセルファイルがどこにあるのか、エクセルファイルを開かずに検索したい時もある。(※1)
方法は色々ある(※2)が、今回はシェルスクリプトでやってみる。(何でもシェルスクリプトでやりたくなってしまう悪い癖ですねほんと。。。)
基本的にはMacで動かしていますが、bashが動く環境ならWindowsでもLinuxでも動くはず。多分。(WindowsのGitBashでなら確認しました!)

※1:試してはないが、エクセルだけでなくOffice系ファイルは同じ方法でいけるはず。今回のシェルスクリプトを、エクセルファイルだけでなくOffice系ファイル全般に使えるスクリプトにアレンジすることもできるはず。
※2:Macならmdfindコマンドとか

カラクリ

どうやってExcelファイルを全文検索するのか。
知っている人も多いと思うが、実はエクセルファイルというのは、xmlファイル群をzipで固めたものだ。
だから、zipを解凍して全xmlファイルについてgrepをかけてやればエクセルファイルの全文検索が可能ということだ。

シェルスクリプトのコード

エクセルファイルを全文検索するシェルスクリプトのコードは以下の通り。

excelgrep
#!/bin/bash

# 引数からgrepの操作内容を取り出す
for arg in ${@}; do
  if [ $(echo ${arg} | grep -vE '\.xlsx$|\.xls$') ]; then
    # FIXME シングルクォーテーションが消えてしまう
    operation=${operation}" "${arg}
  fi
done

# 一つ一つのxlsxファイルに対してgrepする
for arg in ${@}; do
  # *.xlsx以外の引数の場合次のループへ
  if [ $(echo ${arg} | grep -vE '\.xlsx$|\.xls$') ]; then
    continue
  fi

  # zip展開用一時ディレクトリ作成
  tmpdir=$(mktemp -d)
  # grepの標準出力用一時ファイル作成
  tmpgrep=$(mktemp)

  # エクセルファイルを一時ディレクトリに解凍する
  # 標準出力とエラー出力は鬱陶しいので捨てる
  unzip ${arg} -d ${tmpdir} 1> /dev/null 2>&1

  # 全xmlファイルにgrepする
  find ${tmpdir} -type f |
    grep -E 'xml$' |
    xargs -I{} grep ${operation} {} |
    tr '\"' '\n' |
    tr '>' '\n' |
    sed -e 's/<\/.*//' |
    grep ${operation} > ${tmpgrep}

  # 検索文字列があればファイル名とその内容を出力する
  if [ $? = 0 ]; then
    # FIXME
    # awkを使って出力しているため、grepの--color=autoが効かない
    cat ${tmpgrep} | awk '{print filename": "$0}' filename=${arg}
  fi

  # 一時ディレクトリとファイルを削除
  rm -r ${tmpdir}
  rm ${tmpgrep}

done

インストール方法

(1)PATHが通っているディレクトリに配置するか、配置したディレクトリのPATHを通す

例)
・~/binというディレクトリを作成し、本スクリプトを配置
・~/binのPATHを通す

(2)実行権限を与える

chmod +x excelgrep

使用方法

基本的にgrepコマンドと同じような使い方ができる。

# カレントディレクトリ内のエクセルファイルに対して全文検索を行う
excelgrep '検索文字列' *.xlsx
# カレントディレクトリ以下の全てのディレクトリ内のエクセルファイルに対して全文検索を行う
find . -type f | grep -E 'xlsx$' | xargs -I{} excelgrep '検索文字列' {}

使用例

普通にgrepコマンドのように使用し、同じように出力を得ることができる。

$ excelgrep 'test' *.xlsx
test1.xlsx: test1
test2.xlsx: test2
test3.xlsx: test3

オプション

基本的にgrepコマンドと同じオプションが使える。

  • 大文字小文字を区別しない
    -i

  • 正規表現
    -E

例)大文字小文字を区別しないor検索
excelgrep -iE '検索文字列1|検索文字列2' *.xlsx

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
16