Doc-ja Advent Calendar 2013 兼 拡張 POSIX シェルスクリプト Advent Calendar 2013、12日目の記事です。
今日は翻訳作業に役立つツールを 2つ紹介します。
単語ごとの差分を表示する wdiff
コマンドと、
その日本語対応版 jwdiff
コマンドです。
wdiff の紹介
wdiff
はテキストデータの差分を単語ごとに示してくれるツールです。
一般的によく利用されるテキストデータ差分表示ツールである diff
は、
行ごとに差分を表示します。
$ diff -u en.txt.old en.txt
--- en.txt.old 2013-12-12 02:16:42.309525648 +0900
+++ en.txt 2013-12-12 02:44:11.417561919 +0900
@@ -1,6 +1,6 @@
-Hello, guys
+Hello, guys.
-I have an pen. That is a pen.
+I have a pen. That is a pen too.
Regards,
- --Boo Bar
+ --Foo Bar
これに対し wdiff
は単語ごとに差分を表示します。
このため、文章の一部のみが書き変わったテキストの違いを見つけるのに適しています。
$ wdiff en.txt.old en.txt
Hello, [-guys-] {+guys.+}
I have [-an-] {+a+} pen. That is a [-pen.-] {+pen too.+}
Regards,
[---Boo-]
{+--Foo+} Bar
git の git diff --word-diff
のように内蔵の差分表示機能に
wdiff
相当の機能も持ったものもあります。
Mercurial の hg diff
のように wdiff
相当の機能がないものでも、
unified 形式の差分が出力可能であれば、それを wdiff
+
-d
(--diff-input
)
オプションに通すことで、単語ごとの差分に変換することもできます。
$ hg diff |wdiff --diff-input
…省略…
wdiff の問題点
wdiff
コマンドは、翻訳作業で利用するには致命的な
「日本語に対応していない」という大きな問題があります。
上の wdiff
の実行例の出力をよく見るとわかりますが、実は wdiff
は「単語ごとの差分の表示」ではなく、
「空白区切りの語ごとの差分を表示」しているに過ぎません。
日本語のように単語区切りなどで空白文字が入らないテキストに対しては、
あまり威力を発揮できません。
$ diff -u ja.txt.old ja.txt
--- ja.txt.old 2013-12-12 02:33:03.437888390 +0900
+++ ja.txt 2013-12-12 02:32:58.325800783 +0900
@@ -1,6 +1,6 @@
-よう、野郎ども
+よう、野郎ども。
-俺はペんを持っている。あれはペンだ。
+俺はペんを持っている。あれもペンだ。
じゃあの。
- --ブー バー
+ --フー バー
$ wdiff ja.txt.old ja.txt
[-よう、野郎ども
俺はペんを持っている。あれはペンだ。-]{+よう、野郎ども。
俺はペんを持っている。あれもペンだ。+}
じゃあの。
[---ブー-]
{+--フー+} バー
jwdiff を作ってみた
ずいぶん前から日本語の文章に対しても wdiff
を使いたい欲求があったのですが、
なんとなく放置してはや数年が経過…。そしてつい先々月、急に思い立ち、
ようやくこの欲求を叶えるコマンドを作りました。
それが jwdiff
です。
MeCab を利用して日本語の文章を分かち書きに変換し、それに対して wdiff
を適用、
最後に分かち書きを解くだけの、簡単な bash スクリプトです
(ksh でも動きますが、現在のところ zsh は未対応)。
動作には wdiff
コマンドのほかに MeCab の mecab
コマンドが必要になりますので、実行前に適宜インストールしてください。
jwdiff
を利用すれば、日本語の文章に対してもいい感じで単語ごとの差分を表示できます。
$ jwdiff ja.txt.old ja.txt
よう、野郎ども{+。+}
俺はペんを持っている。あれ[-は-]{+も+}ペンだ。
じゃあの。
--[-ブー-]{+フー+} バー
そして英語の文章に対しても威力を発揮します。
jwdiff
なら空白区切りでない単語ごとの差分を表示できます。
$ jwdiff en.txt.old en.txt
Hello, guys{+.+}
I have [-an-] {+a+} pen. That is a pen {+too+}.
Regards,
--[-Boo-]{+Foo+} Bar
jwdiff の問題点と回避策 (colordiff)
wdiff
には --less-mode
(-l
) というちょっと気持ち悪い名前のオプションが
あります。これを指定すると、差分情報を色付きで出力するようになります。
何故か出力先が端末の場合は機能しないので、
ページャーなどを通す必要があります。
$ wdiff --less-mode en.txt.old en.txt |less -R
…省略…
$ jwdiff --less-mode en.txt.old en.txt |less -R
…省略…
残念なことに、日本語文章で --less-mode
を使うと文字が化けます。
色付けしたいときは代わりに colordiff
コマンドを利用しましょう。
colordiff
は行を跨いだ wdiff
の差分の色付けに対応していないようなので、
jwdiff
に -n
(--avoid-wraps
) オプションを指定したほうがよいです。
zsh ユーザーなら次のようなグローバルエイリアスを設定すると便利かもしれません。
alias -g D='|colordiff |$PAGER'
alias -g WD='|jwdiff --diff-input --avoid-wraps |colordiff --difftype=wdiff |$PAGER'
使用例:
$ git diff WD
…省略…
$ git log -p WD
…省略…
colordiff の問題点
現在の colordiff
は、「入力をすべて読み終わってから色付け処理する」というちょっと困った仕様になっています。
大量の差分情報が含まれた git リポジトリで git log -p |colordiff
すると、
長い時間帰ってきません。 機会があれば修正したいと思っていますが、いつになるやら…。
DocDiff
今回 jwdiff
を作ったのですが、すでに同等+αの実装が存在しました。
- DocDiff - Compares two text files by word, by character, or by line
ネタ募集
拡張 POSIX シェルスクリプト Advent Calendar 2013の今後のネタですが、 相変らず 10日分くらい足らなそうな見込みです。
もしよろしければ、 シェルスクリプトの関する疑問・質問、スクリプトの添削依頼、やって欲しいネタをください!! 記事に反映できるかどうかは内容や私の実力次第ですし、お礼は特にご用意できませんが、 よろしくお願いします。orz
ところで、12月25日はクリスマスな上に、
OSS 界隈で地味に活躍されているふみやすさんの誕生日ですね!
っ http://www.amazon.co.jp/registry/wishlist/27M7TV8CEEF6G?sort=priority
逆に、あなたの書いた OSS や Blog や Advent Calendar が気に入ったら何か送りたく なってしまうかもしれないので、プロフィールや Web サイトに あなたの Amazon 欲しいものリストの URL を貼っておいてくださいね!
私が勤める OSSTech っていう某弊社で社員募集しているようです。 人材紹介会社を介さなければ、入社後に 20万円のボーナス! 「ふみやすっていう人に紹介された」と言ってもらえると私にもボーナス!! → https://www.osstech.co.jp/recruit/
よろしければ、これまで参加した/参加予定のほかの Advent Calendar もどうぞ。
- Ansible Advent Calendar 2023
- シェル芸 Advent Calendar 2023
- 闇の魔術に対する防衛術 Advent Calendar 2023
- Ansible Advent Calendar 2023
- Ansible Advent Calendar 2020
- DNS温泉 Advent Calendar 2019
- OSSTech Advent Calendar 2019
- Ansible Advent Calendar 2018
- OSSTech Advent Calendar 2018
- Debian/Ubuntu Advent Calendar 2017
- Linux Advent Calendar 2017
- Shell Script Advent Calendar 2017
- Shell Script Advent Calendar 2016
- OpenLDAP と仲間たち Advent Calendar 2015
- Postfix Advent Calendar 2014
- 拡張 POSIX シェルスクリプト Advent Calendar 2013