LoginSignup
1
0

More than 3 years have passed since last update.

絵文字が含まれるファイルを再帰的にgrepしたい

Last updated at Posted at 2021-02-21

英語/日本語で調べたけど中々見つからなかったので、同じようなことをやりたい人のご参考になれば嬉しいです :pray: :sparkles:

:three: 行まとめ

  • 絵文字を Font Awesome に置き換えたい! :bulb:
  • 絵文字を含むファイルってどこだっけ...? :sweat_drops:
  • 再帰的に絵文字を探す emoji-search を書いてみた! :wrench: :dash:

:mag: emoji-search の実行例

例えば未踏ジュニアの公式Webサイト (:octocat: mitou/jr.mitou.org) のルートディレクトリで emoji-search を実行すると、次のような結果が得られます。

╭─○ yasulab ~/jr.mitou.org
╰─○ emoji-search
alumni.md: 🆕 今年度より採択開始!
guideline.md: ※ 2021年度の応募は3月上旬から受け付ける予定です。 🙇‍
README.md: どの箇所を更新するにせよ、Webブラウザが一番簡単だと思います...!! 😆
_site/README.md: どの箇所を更新するにせよ、Webブラウザが一番簡単だと思います...!! 😆
_site/guideline.html: ※ 2021年度の応募は3月上旬から受け付ける予定です。 🙇‍
_site/download.html: 提案書の準備ができたら応募フォームへ! 😆
_site/download.html: ※ 2021年度の応募は3月上旬から受け付ける予定です。 🙇‍
mentors.md: 🆕 今年度より採択開始!
download.md: 提案書の準備ができたら応募フォームへ! 😆
download.md: ※ 2021年度の応募は3月上旬から受け付ける予定です。 🙇‍

:gem: emoji-searchコマンドの中身

当初はシェルスクリプトのgrep/findなどで書こうとしたのですが、簡単ではなさそうだったので断念 :sweat:

標準ライブラリだけで書きたいなーと思って色々試したところ、Ruby で書くのが早そうだったので、結果として下記のようなコードになりました。コメントも付けてみたので、コードを読むご参考になれば! :pray: (grepコマンドは使っていませんがgrepっぽい見た目に近づけています)

# Binaryファイルを弾くよ
require "open3"
def is_text_file?(filename)
  file_type, status = Open3.capture2e("file", filename)
  status.success? && file_type.include?("text")
end

# 絵文字を探していくよ
Dir.glob('**/*').each do |filename|
  # `.git`ディレクトリやBinaryファイルを調べると遅くなるのでスキップ
  next if filename.start_with? "."
  next unless is_text_file? filename

  File.open(filename) do |f|
    f.each_line do |line|
      # BMP 外の文字が含まれるか否かで探して、見つけたら出力するよ
      # 詳細: https://qiita.com/yusukeyamane/items/79764e36cc5bd89bc9a4#comment-e879ba227ab95b006017
      puts("#{filename}: #{line}") if line.match?(/[^\u0000-\uFFFF]/)
    end
  end
end

あとは bash/zsh などで emoji-search をエイリアスに設定して、

alias emoji-search="ruby /path/to/emoji-search.rb"

調べたい場所で emoji-search すると完成です :book: :mag: :dash: 今回は標準ライブラリのみで書いているので、Ruby が入っていれば大体使えるはず...!!

皆さんの絵文字ライフが快適になれば嬉しいです! :laughing: :sparkles:

:white_check_mark: オマケ: なんで /\p{Emoji}/ を使わないの?

他のQiita記事のコメント欄@scivola さんが解説されていますが、予想以上にマッチしてしまっていたため別のアプローチを採りました :sweat:

例えばコードの一部を次のように変更し、

- puts("#{filename}: #{line}") if line.match?(/[^\u0000-\uFFFF]/)
+ puts("#{filename}: #{line}") if line.match?(/\p{Emoji}/)

再度 emoji-search コマンドを実行すると、 # を含む部分なども引っかかってしまいました :eyes: :sweat_drops:(Ruby 2.7.2 で実行)

╭─○ yasulab ~/jr.mitou.org
╰─○ emoji-search

... (省略)

download.md: ## 提案書テンプレート {#template}
download.md: 提案書のテンプレートを以下からダウンロードして、PDFに変換後、[応募フォーム](#ready)からアップロードしてください。
download.md: <a href="https://jr.mitou.org/assets/other/mitoujr_application_2021.zip" class="button">Word・Pages を使う</a>
download.md: <a href="https://docs.google.com/document/d/1hjDYf2DbFBkXLyrAl9HKKc9sS40XbZ_iN2j-HKZXD9g/edit?usp=sharing" class="button" target="_blank">Google Docs を使う</a>
download.md: ## 提案書サンプル {#sample}
download.md: <a href="https://jr.mitou.org/assets/other/2020_application_samples.zip" class="button">過去の提案書を見る</a>
download.md: ## 準備できた? {#ready}
download.md: <p class="text-center">提案書の準備ができたら応募フォームへ! 😆</p>
download.md: ※ 2021年度の応募は3月上旬から受け付ける予定です。 🙇‍

他の正規表現もいくつか試したところ、今回の用途に限って言えばコメント欄にある /[^\u0000-\uFFFF]/ だと欲しい情報が得られたので、今回はその正規表現を使っています :pray: :sparkling_heart:

絵文字は奥が深いですね... :eyes: :thought_balloon:

1
0
0

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
1
0