Web Developer's Struggle Memories

日々の業務から思ったこと、学んだことを書き連ねていきます。

日記:2018-05-08

今日からエンジニア 日記なるものを書いていこうと思う。

個人的には「技術ブログ」だとハードルが高く感じるので。 理由は、技術ブログは一つのテーマについてある程度まとまった内容、分量を書かないといけないと思っているから。

そうじゃなくて、日記なら今日あったことを書くだけなので全然ハードルは低い。ここまで下げたのに続かなかったら… とにかくやりますわー。

今日やったこと

公開したパッケージの改修

ちょっと前に npm に cmd-ranking というcliツールを公開した。

www.npmjs.com

今日はこのツールの、「コマンド履歴にマルチバイト文字(日本語の文字など)が含まれていると、コマンドが動作しない」というバグの改修をやった。

このツールの肝は正規表現なのだが、やはり躓いた。正規表現はずっと学び続けるもののように感じるな。 以下のようなコマンドをプログラムの中で実行するのだが、

# パイプ2つ目が既にバグってる(後述)

> cat ~/.zsh_history | LC_ALL=C sed -e 's/.*;//' | sort | uniq -c | sort -r | head -n ${number}

これだと、zsh_history マルチバイト文字が含まれていると、sort のとこで以下のようなエラーが発生する。

sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `su' and `正覃\257胁\250烯\276'.

結論から言うと、上記のコマンドに以下のコマンドを追加した。

# \\ と重ねているのは、ソースコード自体はnodejsで書いているから

perl -pe 's/[^\\x00-\\x7F]+//g'

最初はこれを sed -e を使ってマルチバイト文字を空文字列で置換しようとしてたのだが上手くいかなかったのだが、 先輩エンジニアの人の力をお借りし、perl で一発でいけて感動した。

課題

このパッケージにはもう一つバグが残っている。

zsh_history のデフォルトのファイル出力フォーマットは、

 : 1525618121:0;vim index.html

のようになっており、セミコロン (;) で以前の文字列は不要なので、これを削除したい。 しかし、上で書いた正規表現 sed -e 's/.*;//' だと、

 : 1525791458:0;cat ~/.zsh_history | LC_ALL=C sed -e 's/.*;//'

のように、1つのコマンドにセミコロンが2つ存在すると、そのコマンドが取得できない(この例だと //' となってしまう)ので、 これは明日以降対応する。

では(・ω・)ノ


P.S.

他には GatsbyJS を触り始めたけど、今日は書かない。