18
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2022-09-09

概要

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

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

カラクリ

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

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

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

excelgrep
#!/bin/bash

main() {
  # 引数からgrepの操作内容を取り出す
  operation=""
  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

    # 一時ファイルなら何もしない
    if echo "${arg}" | grep -qE '^~\$'; then
      continue
    fi

    target_file="${arg}"

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

    # エクセルファイルを一時ディレクトリに解凍する
    # 標準出力とエラー出力は鬱陶しいので捨てる
    unzip "${target_file}" -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="${target_file}"
    fi

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

  done
}

main "${@}"

インストール方法

(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
18
19
6

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
  3. You can use dark theme
What you can do with signing up
18
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?