それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

xargsで複数行のコマンドを実行する方法

xargs で複数行のコマンドを実行したい。

出来ない・・・

ls *.txt  | xargs -I@ echo @ ; sleep 1

forループならできるんだけど、for ループだとどうしても不便。

xargs でシェルコマンドを作って渡す.

xargs だと限界があるので、もうシェルの文字列にして渡すしか、他に選択肢がない。

ls *.txt  | xargs -I@  sh -c 'echo @ ; sleep 1'

これなら動くんです。動くんです。

xargs が1つ実行するたびに、 sh -c 'echo @ ' の@ の部分にファイルを文字列として入れて渡してくれる。

bash でもいい

sh だと機能が少ないので、bashにしてやるという手段も取れる。

ls *.txt  | xargs -I@  bash -c 'echo @ ; sleep 1'

条件分岐も

もうここまできたら、なんでもあり。シェルに文字列渡すんでス。ここなら何でもありです。条件の入力だってできちゃう。

ls *.txt  | xargs -I@  bash -c ' [[ @ =~ 2017 ]]  echo @ ; sleep 1'

脱 for文

これで、for がなくても戦える。

なんだけど、ここまでする必要あるかなぁ。コマンドを履歴に残したいとかパラレルに実行したいときには相当便利だけど、コードメンテしにくい。。。両刃の剣か。

参考資料

HTTPSサイトからの遷移時に内部サイトのリファラがもれないようにする。サーバー側設定Referrer-Policy

nginx をつかってブラウザにリファラをおもらししないように命令する

社内のファイルサーバーのリファラURLが漏れると恥ずい。いやまずい。

何がまずいかというとファイル名が漏れてしまったり、アクセス元のURLとして晒されたり、検索インデックスに追加される恐れがあるからだ。

server {
    add_header Referrer-Policy no-referrer always;
}

これを書くと、ブラウザがリファラを送らなくなる。一般的なブラウザの場合だけどね。 サーバー側で制御できるものはしちゃったほうが良いね。

リファラでファイル名がバレるとそれを使っってターゲット・フィッシングメールが作れるもんね。

選択肢

origin
same-origin
strict-origin

origin

基本的に使わない。このサイトからリファラを送るならURLにパスを入れないでくれ。 リファラURLでなく、リファラドメインだけが送られる。

strict-origin

基本的にコレ。このサイトでは同一ドメインリファラを送ってくれ。 HTTPでセットされたとき、HTTP→HTTP(s)で送られる、HTTPSでセットされたとき、HTTPSHTTPSのみ、HTTPS→HTTPはリファラ対象外。

no-referrer

このサイトではリファラを絶対送らないでくれ。というヘッダ。

詳しくは、参考資料のMDNページ

参考

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Referrer-Policy

tesseractでPDFを検索可能にしてみる

tesseract を使ってPDFをOCRする

https://pypi.org/project/pypdfocr/ というツールを見つけたので、使ってみる

残念なお知らせです。

python 3 系ではシンタックスエラーで動きません。

インストールのログがこちら。

takuya@deskew$ pip install pypdfocr
Collecting pypdfocr
  Using cached https://files.pythonhosted.org/packages/c3/23/1bf42cb12af63d498fcd425882815c21efef37800514dbad9fa28918df5e/pypdfocr-0.9.1.tar.gz
Requirement already satisfied: pillow>=2.2 in /Users/takuya/.pyenv/versions/3.7.0/lib/python3.7/site-packages (from pypdfocr) (5.3.0)
Collecting reportlab>=2.7 (from pypdfocr)
  Using cached https://files.pythonhosted.org/packages/d8/d5/583e6235d0c690c2cda2cd080c60413fbf7be8d8e012e003087202edfb50/reportlab-3.5.9-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
Collecting watchdog>=0.6.0 (from pypdfocr)
  Using cached https://files.pythonhosted.org/packages/bb/e3/5a55d48a29300160779f0a0d2776d17c1b762a2039b36de528b093b87d5b/watchdog-0.9.0.tar.gz
Collecting pypdf2>=1.23 (from pypdfocr)
  Using cached https://files.pythonhosted.org/packages/b4/01/68fcc0d43daf4c6bdbc6b33cc3f77bda531c86b174cac56ef0ffdb96faab/PyPDF2-1.26.0.tar.gz
Collecting evernote (from pypdfocr)
  Using cached https://files.pythonhosted.org/packages/f9/6b/877f8edef8ef040d32eb38f3bf6322ba334de9d10614d8db9d869c162fc1/evernote-1.25.3.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/private/var/folders/ff/fc49g5wd6xncjylvwy4tdygc0000gn/T/pip-install-yx8p73r2/evernote/setup.py", line 6
        exec x
             ^
    SyntaxError: Missing parentheses in call to 'exec'

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/ff/fc49g5wd6xncjylvwy4tdygc0000gn/T/pip-install-yx8p73r2/evernote/

しかたないので、pyenv で切り替えて使ってみることにしたい。

ちょっと困りますよね。python2系は流石にちょっとと。でも動けばいいしPDFをぱぱっと扱えるならpython2でも我慢する。

pyenv global 2.7.15
pip2 install pypdfocr

tesseractが無いばあい、いれる必要がある。

brew install tesseract

OCR をしてみる

pypdfocr my.pdf

うーん、めっちゃ時間かかる。時間かかる割にtesseractの調整をしてないから精度がいまいちな気がする・・・・・日本語も取れないし。tesseractをちゃんと設定しないとダメだし、所詮OCRなので・・・諦める。

参考資料

https://pypi.org/project/pypdfocr/

画像をpdfに変換する

画像を、PDF(画像埋込)に変換する

img2pdf を使ってみる

img2pdf のインストール

img2pdfは pip で提供されている pythonのコマンドなので pip でインストールする。

pip install img2pdf

これで準備出来た。

使ってみる。

 ls *.jpg | xargs -I@ img2pdf @ -o @.pdf

ちゃんとしっかり変換できた。

pdf を1枚にまとめる。

pdftk *.pdf cat output  combined.pdf

pdf は1枚ずつ変換してPDFにまとめたほうが良いっぽい

2019-07-27 追記

このコマンドは、PDF にJPEGをそのまま埋め込みして変換するので、再エンコードが発生せずに、元のJPEGのまま埋め込める。

言われてみたらたしかに、そうだった。その視点はなかった。

そうだよね。確かこのコマンドを調べて記事にした頃、magick だと変換するので遅いし劣化するから困って無圧縮(無変換)で探してたかもしれない。メモから記事にしたのですっかり忘れてる。

参考資料

Macbook"13 を限界突破して解像度(2880x1800)を無理やりで使う。DisplayMenu

ThinkPadとか見てたらめっちゃ文字小さくてデスクトップが広くて羨ましい。

わたし、ぜんぜん老眼じゃないですよ。小さい文字のほうが見やすくて好きなくらいです。

MacbookRetina解像度をオフにして、Windowsのノートパソコンのような極小な文字で、広大なデスクトップを確保したいと思いました。

だって、小さいって良いことだよね。 小っちゃいって事は便利だねっ

Mac App Store の Display Menu を使うと簡単です。

Display Menuのアプリケーションを使うと、Windowsの人みたいに、限界まで小さくしたデスクトップ環境を確保できます。

f:id:takuya_1st:20181031022201p:plain

Retina解像度をオフにしたらこんな感じ、広い、ただただ広い。ほんとひろい。

これ、MacbookProの13 なんですよ。2560x1600なんですよ、 2880x1800まで引っ張り出せるんです。

f:id:takuya_1st:20181031022204p:plain

欠点

Retina解像度じゃなくなる。

マウス移動が大きくてトラックパッドが足りなくなる。

でもね 2560x1600とか 2880x1800とかにもなると、Retina解像度じゃなくても気にならない。 でもね、MBP 2016 以降の大きなトラックパッドだと快適だったりする。

眼がおかしくなる。ただ、長時間やってるとめっちゃ疲れるんで、たくさん文章を書くとき、集中したいとき、めんどくさいコードを追いかけるときに限定しても良いかもしれない。

付加価値的なメリット;覗き見防止

覗き見防止のフィルタを貼るくらいなら、いっそ限界まで最大の解像度にしたらどうでしょうか。広くて仕事捗るし、画面の文字が小さくて1メートル以上離れたら多分見えない。

なんなら電車で、横に座ってる人でも視認は大変なレベルだと思います。

RetinaMBAだと意味ないよ

RetinaMBAでコレを利用して解像度が増えないというレビューを見かけたんですが、Retinaを切ってドットbyドット(液晶モニタの本来の解像度)にするので、MBAの人はMBA Retianaを座して待つしか無いです。(2018-10-31 発表があり、Retina MBA がついに出ました)

課金

課金したらRetina解像度に戻せるメニューが増えるようです。 いちいち環境設定を開かなくて良くなるのは便利ですね。

参考記事

www.atmarkit.co.jp

ものすごく疑問なんだけど、なぜこの記事が、Windows Insiderにかかれているんだろう

xargs で実行前に確認のY/Nを実行する interactive

xargs のコマンド実行前に確認する

xargs -p 

これで、毎回確認できる

使ってみた例

takuya@temp$ ls *.jpg | xargs -p -I@ --verbose mogrify -crop 2886x3700+0+0 @ 
mogrify -crop 2886x3700+0+0 out-000.jpg  ?...y
mogrify -crop 2886x3700+0+0 out-000.jpg
mogrify -crop 2886x3700+0+0 out-001.jpg  ?...y

コマンド実行前に確認のプロンプトで確認入力を促せる。

正直使い所が難しい

xargs を使うときは、大量に実行したいときがほとんどなので、ちまちまとY/N尋ねられる用途とは相容れないと思うのね。

ただ、ある程度のファイル数が少ないときで、シェルスクリプトから削除を実行するときにインタラクティブに質問するのは良いと思います。たとえば、ゴミ箱を空にするときとか。

一番便利なのは、コマンド確認

とりあえず、-p をつけて実行コマンドを確認してから、 Ctrl-C で抜けて、その後-p を外して実行すれば、「1つ目」のコマンドを確認でき、1つ目さえ通ればあとは問題ない場合が多いので、ミスが少なくなる。

https://unix.stackexchange.com/questions/300095/how-do-i-get-xargs-to-show-me-the-command-lines-its-generating-without-running

xargs 実行するコマンドを確認表示してどこまで進んだかを見やすくする

xargs 便利ですよね。

コマンドを明示的に1つずつ実行したり、ファイルをまとめて実行したり。実行する子プロセス数(スレッド)を指定できたり。

まとめて処理しているときにどこまで処理しているかを見ながらやってほしい

たとえば、rsync の場合だと rsync --progress すると転送情強のファイル名が見れるじゃん。
同じように、今実行しているファイルがどれか、進捗をxargs でできると楽しそう。

オプション -t

次に実行するコマンドを表示してから実行してくれる -t を使うとできる

これで、表示がでるので何を実行しているのか確認ができる。

たとえば、画像を1000枚変換するときに、今何枚目を実行しているかわかる。

takuya@temp$ ls *.jpg  | xargs -t -I@ -P 1 mogrify -crop 2886x3700+0+0 @ 
mogrify -crop 2886x3700+0+0 out-000.jpg
mogrify -crop 2886x3700+0+0 out-001.jpg
mogrify -crop 2886x3700+0+0 out-002.jpg
mogrify -crop 2886x3700+0+0 out-003.jpg
mogrify -crop 2886x3700+0+0 out-004.jpg
mogrify -crop 2886x3700+0+0 out-005.jpg
mogrify -crop 2886x3700+0+0 out-006.jpg
mogrify -crop 2886x3700+0+0 out-007.jpg
mogrify -crop 2886x3700+0+0 out-008.jpg
mogrify -crop 2886x3700+0+0 out-009.jpg

例2

たとえば、フォルダに対して、なにか処理をして、その結果が必要なとき。 このときは、標準出力を分けてあげればいい。

takuya@tmp$ find -type f | xargs -I@ -P 5 -t md5sum @ >> md5-list.txt

もう ps をwatch しなくていい。

たくさんのファイルを処理中は、ps を見たりしてたんだけど、Verboseに今の実行コマンドをプリントして表示してくれるなら、めっちゃ便利。

2021-03-17

標準出力を分ける方法を追記

参考資料

https://stackoverflow.com/questions/842401/is-xargs-t-output-stderr-or-stdout-and-can-you-control-it

nginx で proxyPassReverse的なのを実現する。

apache のproxyPassReverseって便利だよね。

とくに静的ページを作るのに便利。記事公開するだけのSPAなんぞいらねーよね。ってとき便利

でもnginx で出来ない。→ 置換すればできるよ。

URIディレクトリを修正する方法の例

プロキシリクエストの結果を書き換えられるので、それを仕込んで見る。

応答はsub_filter で置換できる。

   location ~/blog/(.*) {

      # rewrite ^ $1 break;
     proxy_set_header Host $host;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header X-Forwarded-Proto $scheme;

     set $nocache 0;

     if ($arg_filter_distance = "") {
         set $nocache 1;
     }
     proxy_cache_bypass $nocache;
     proxy_no_cache $nocache;


     proxy_pass http://127.0.0.1:1234/$1;


     sub_filter '/static'  "${uri}static";
     sub_filter '/task'  "${uri}task/";
     sub_filter_once off;
   }

ポイント

ここで、proxy 取得したHTMLの「コンテンツを書き換え(sub_filter)」ている。

     sub_filter '/static'  "${uri}static";
     sub_filter '/task'  "${uri}task/";

ただし、JSにかかれてJSでLocationを管理されると手出しができないので注意。

HTML ファイル以外を書き換えたい。

「sub_filter 」はContent-Typeを見ていて、Content-Typeがtext/html 以外を編集しない。

octet-stream や video を書き換えても徒労に終わるからだ。ただm3u8やjs など文字列は書き換えても良い。

その場合は、Content-Typeを明示する

sub_filter_types application/x-mpegURL;      
## 複数書くときはスペースで列挙
sub_filter_types text/html application/x-mpegURL; 
## ワイルドカードも
sub_filter_types text/* application/*; 

このように、sub_filter_types を使って subfilter が動作するファイルを追加する必要がある。

複数のタイプの書き方やワイルドカードの例については、本家のドキュメントに具体的な指示がないので、たぶんnginx 一般の書き方なんだろう。

どういうときに使えるのか

サブディレクトリに非対応なWebアプリケーションを無理やりサブディレクトリで展開するのに便利。

サブディレクトリにしたほうが便利なアプリケーションがある。たとえば、複数のブログとか。たとえば、JiraとConfulenceとか。

2023-09-28

sub_filter で検索したときに、でてこなかったので書き換え

certbot がLetsEncryptのワイルドカード証明書に対応してたので作ってみた

certbotワイルドカード対応ですって!

Cerbot使ってますか?めっちゃ使いますよね。手軽なHTTPS通信には不可欠です。

なんと、CertBotワイルドカード対応ですって。ツイートは2018-05-02だから半年前には対応してた模様。知らんかった。最近は情報密度薄くて、こういう情報を手に入れるのが難しくて困る。

該当のツイート

早速やってみる。

Certbot最新版しか対応してないので、debなどのパッケージでは追いつけない。んあのでgithub から最新版のCertbotを持ってくる。

git clone https://github.com/certbot/certbot.git
cd certbot

そのうち最新版がLinuxディストリから配布されるとは思いますが、いまはgithubからダウンロード。

発行してみる。

手順は、通常のCertbotとほとんど同じです。

./certbot-auto \
certonly \
--manual \
-d  example.com \
-d  \*.example.com \
--agree-tos --manual-public-ip-logging-ok \
--preferred-challenges dns-01 \
--server https://acme-v02.api.letsencrypt.org/directory

コレを実行するとドメインの所有者確認をTXTレコードで要求される。

dns-01 からの指令が来る

_acme-challenge サブドメインのTXTレコードを書き換えてくださいねって。

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

yAXjSm2yF1n-9ZHlWWTQ-PFP_PHvI6Yy6YzpHqitKeQ

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to ContinueCleaning up challenges

TXTレコード登録のためにDNSを書き換えに行く。

f:id:takuya_1st:20181025162347p:plain

DNSサーバーに書き換えに言ってあとは結果待ち

ちょっと待ってれば、すぐに終わる。

Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2019-01-23. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
   

http サーバに組み込んで通信する。

うおーーーやったね。

あこがれのワイルドカード証明書だ。一度は使ってみたかったワイルドカード証明書

しかもタダって良いんですかね。LetsEncryptには感謝です。

f:id:takuya_1st:20181025162034p:plain

発行時の注意

ワイルドカード証明書なので

*.example.com で発行した場合 aaa.example.comワイルドカード対象になるんだが、 サブドメインなしの example.com は対象にならない。

当たり前と言っちゃ当たり前なのですが、証明書エラーを出したのは私です。

なので、発行する場合は、ドメイン指定を使って、次のようにしました。

-d  example.com \
-d  \*.example.com \

これで、1枚の証明書で、example.com と、*.example.com のどちらも使える証明書になる。サブドメインサブドメインなども同じなると思う。

すでにドメインの証明書を持っている場合。

すでに発行済であれば、発行済のドメインの証明書をrevoke すると良い。

./certbot-auto revoke --cert-path=/etc/letsencrypt/live/example.com/cert.pem

または削除コマンドで削除する。

削除する

./certbot-auto delete 

これで、新規で証明書を作れるようになるのでめでたし。

参考資料

Let's Encrypt (certbot) でワイルドカード証明書できた!

<Macbook>のタッチバーで常にF1-F12を表示するアプリを選ぶ。

mac のタッチバーで、Fnキーを押さずにF12を押す。

MacのタッチバーでFキーを常に表示するアプリ設定して、いちいちFnキーを押さないで済むアプリを指定する。

設定例

環境設定→キーボード→ショートカット

f:id:takuya_1st:20181016174152p:plain

なんでメモするのか

Macbookのタッチバーの設定がキーボード・ショートカットキーの項目にあることを忘れがち

どんなときに便利なのか

なんでこんな設定をわざわざやるの?

ファンクションキー F1- F12 が前提になっているアプリケーションは非常に多い。とくにWindowsと共通化されているアプリケーションには必須とも言える項目だと思うんだ。

など、開発する環境のIDEや、デザインツールはこれらの設定をしておいたほうが無難。

っていうか、いまどきパソコンなんて開発者しか使わないんだし、Macbookのタッチバーが開発者にとって不便な機能であるのにゴリ押しした設計思想に疑問を覚えずにいられない。

dateコマンドで unix epoch time の int 秒を取得する

date +"%s"

bash を使ってて、今の時間を int 表記でタイムスタンプとしてほしいよねってとき。

takuya@~$ date +"%s"
1538853051

こうすれば、Unix秒、つまり1970 からの経過秒数が取得できる。

知っておくと便利だし。Gnu Date の時刻フォーマットなので、PythonRubyなどその他の言語でも同じように扱うことができる。便利。

参考資料

  • man date

ターミナルでCPUの使用率の変化を眺める。s-tui

CPU負荷率の変化を見たい。

サーバーのCPUの負荷率(利用率・使用率)が時間経過とともにどう変わっているかを少し見たいとき。

htop だとじっと眺めておいて、「今」のCPU使用率がわかるんだけど、時間を横軸にとり変化を視覚化できる物があればと思ってた。

候補となるソフトウェアはいくつかあリマス。いろいろやりたいときはWebGUIでCockpitを使えば良いんでしょうが。

ぱぱっと作業中のCPU負荷率やコマンドをオン・オフしたときの変化を手軽に見たいときもある。

raspi のような極小デバイスでaptとコマンドを同時 実行してるときとかディスクIOなのかネットワークなのかCPUなのかいつも判断に迷う

ターミナルでCPUモニタリングをする s-tui 

python のpip パッケージの s-tui というものを知った。

インストール 

インストールはpipだけでオッケ

pip install s-tui 

実行

takuya@~$ s-tui

私の場合、バイナリが次の場所にありました。

takuya@~$ which s-tui
/Users/takuya/.pyenv/shims/s-tui

ここにインストールされました。

実行してみた結果

設定もTUI/CLIでできるし、キーボードから操作や設定も変えられる。ストレステストがありますね、別途インストールが必要みたい。

f:id:takuya_1st:20181016173757p:plain

f:id:takuya_1st:20181016173747p:plain

2018-11-15 追記

MBPじゃなくて、Linuxから使うと情報が多かった。 消費電力とか書いてある。楽しい。って眺めてたらgitlab入れた直後にCPU使用率と温度がやばいことに。

f:id:takuya_1st:20181115001430p:plain

もしかしたら、debian-non-free で intel 関連のfirmware-misc-nonfreeを昨日入れたので見えるようになったのかもしれない。

github でLFSを使う

github 遅い。。。

github は基本的に遅いので、ちょっとしたバイナリでも追加すると重くなる。

git だけで使ってる分には気にならないんですが、github と連携してpush にバイナリが混じり始めると遅い。

そこでGitHubでもLFSを使うことに。

githubLFSでデータを送る

github にはLFSでデータを送付することが出来ます。

ローカル git レポジトリでLFSを使う

git lfs track '*.pdf'

ファイルを追加する

git add ./*.pdf

LFSで追加されたことを確認

git lfs ls-files

コミットしてpush

コミット

git commit -m 'initial import to LFS'

プッシュする

git push 

転送速度はLFSのほうが早い??

LFS使ったほうがGithubの転送速度は早いような気がした。

PDFを入れるなよって思われるかもしれないですけど。ちょっと用事がありまして。

takuya@gitbook$ git push
Uploading LFS objects: 100% (86/86), 562 MB | 5.5 MB/s, done
Enumerating objects: 100, done.
Counting objects: 100% (100/100), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (98/98), done.
Writing objects: 100% (99/99), 13.44 KiB | 1.92 MiB/s, done.
Total 99 (delta 1), reused 0 (delta 0)

回線速度によりますけど、LFSは5.5MB/s で、通常のGitのテキストファイルは 2.0MiB/sでした。

LFS使うほうがメリット大きいな。 空いてる方を使うべきだ。ってことかなやっぱ。

LFSを使うときの注意点

Gitのレポジトリのpush先を変えたときに、LFSのログが引き継がれないので注意が必要。

そのうち対応してほしいよね。

関連記事

参考資料

日本語(ローマ字)表記をひらがなにする。

日本語(ローマ字)表記をひらがなにしたい

「shatiku → しゃちく」 にしたい

本日の目的 ローマ字で表現された名前を変換したい。

hatarakusaibou のような名前を ’はたらくさいぼう’のようにひらがな表記に変えたい。

ローマ字を'ひらがな'に変換できれば、ひらがなから漢字にできるかもしれない。

ローマ字→ひらがな→漢字 に変換できればいいよね。

力技もある。

tr 使えばできそうよね。正規表現でパターン網羅すれば良いわけですし。

力技で、 'kakikukeko' を 'かきくけこ' に tr すればいいと思ったけども 変換テーブル用意するのも、めんどくさい

調べたら。 romkan という gem があった

使ってみる

bundle add romkan
require 'romkan'
puts "kitakyuushuu".to_kana

実行結果

$ bundle exec ruby sample.rb 
きたきゅうしゅう

お、行けそう。

使うときの注意点

意外と使い所が難しい。

  • waha にする
  • アルファベットの大文字が混じるとおかしくなるので、事前に小文字化しておくと良い
  • 英単語と混じってる場合、スペースなどの区切りで置換対象から除外する。
  • 子音が連続する単語は置換から除外する。

大文字が行頭に混じると困る。例

>> 'Osaka Namba'.to_hepburn.to_kana
=> "Oさか Nあmば"

小文字にするとまだまし

>> 'Osaka Namba'.downcase.to_hepburn.to_kana
=> "おさか なmば"

それでも 難波を Namba と表記されると辛いし、大阪をOsakaと表記されると辛い。

英単語混じりはつらい

たとえば、 Death March からはじまる異世界をローマ字とすると、次のようになる。

>> text = 'Death_March_kara_Hajimaru_Isekai_Kyousoukyoku'
>> puts text.downcase.gsub(/_/,' ').gsub(/ wa /, 'ha').gsub(/\s|_/,'').to_hepburn.to_kana
=> "であthまrchからはじまるいせかいきょうそうきょく"

連続する単語を置換するには厳しそうだ。

子音(小文字)が連続する単語や、末尾が子音で終わる単語を置換対象から外すというヒューリスティックな解決策しかなさそう。

text = 'Death_March_kara_Hajimaru_Isekai_Kyousoukyoku'
puts text = text.downcase.gsub(/_/,' ')
                .gsub(/ wa /, 'ha')
                .split(/\s+/)
                .map{|e| e=e.to_hepburn.to_kana unless  e=~/[^aiueon]$/ ; e   }
                .join(' ')
# => death march から はじまる いせかい きょうそうきょく

こんな感じ??

母音の連続は扱えない

連続する母音は、省略表記されることが多いのだけど、これをうまく扱う方法が思いつかない。

'osaka'.to_kana
#=> "おさか"
>> 'kyushu'.to_kana
=> "きゅしゅ"

なんに使うの?

日本語のローマ字で書かれた、大量のPDFがあったり、HTMLファイルがあったり、テーブル定義があったりします。 読みにくくて仕方がないので、ひらがな・漢字に変換できれば便利になるよね。

参考資料

ruby - mecab をインストールするときにエラーが出たのでメモ

mecab - ruby を使いたい

久しぶりにmecab をインストールしようとしたら・・・

bundle add mecab 

エラーになるんですね。

extconf.rb:12:in ``': No such file or directory - mecab-config

mecab は extconf で外部ライブラリ(.h)を参照するので、 mecabのインストールが必要でした。

エラーの原因:mecab が未インストールでした。

わたしは、macOS なので brew install します。

takuya@$ brew info mecab
mecab: stable 0.996 (bottled)
Yet another part-of-speech and morphological analyzer
https://taku910.github.io/mecab/
Conflicts with:
  mecab-ko (because both install mecab binaries)
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/mecab.rb

ああ、not installed だ。ずいぶん長い間使ってなかったんですね。つまりMacにしてから数年間一度もmacで使ってないわけだ。

mecab 本体のインストール

brew install mecab
brew install mecab-ipadic

これでインストールは完了

ruby mecab のインストール

bundle add mecab

無事終了しました。

Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using bundler 1.16.2
Fetching mecab 0.996
Installing mecab 0.996 with native extensions
Using romkan 0.4.0
Bundle complete! 2 Gemfile dependencies, 3 gems now installed.
Bundled gems are installed into `./vendor/bundle`

起動テストをします。

動かしてみます。

require 'mecab'
m = MeCab::Tagger.create("-Ochasen")
puts m.parse ("shachou")
bundle exec ruby sample.rb 
shachou shachou shachou 名詞-固有名詞-組織              
EOS

オッケ。

gem install でシステムに依存しない extconf にしてくれたら嬉しいんだけどなぁ。