7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

最強uconvコマンドで全角⇔半角, ひらがな⇔カタカナ, 大文字⇔小文字の変換をシェルスクリプトで行う

Last updated at Posted at 2022-09-03

はじめに

uconv は ICU が開発した文字変換のコマンドです。文字コードを変換したり、全角を半角に変換したり、大文字を小文字に変換したり、ひらがなをカタカナに変換したりする場合、tr コマンドや nkf コマンドを使って変換するという例を多く見かけます。しかし tr コマンドは Unicode に対応していなかったり POSIX ロケール以外の対応に問題があったりします。また nkf コマンドは Network Kanji Filter の略であることからもわかるように基本的に日本語にしか対応していません。そういった時に使えるのが uconv コマンドです。uconv コマンドはあらゆる国の文字種や文字コード変換に対応しており、Unicode 正規化や BOM の追加や削除にも対応しています。

tr コマンドは標準でインストールされているというメリットがありますが、日本語に対応する必要があるシェルスクリプトで、コマンドのインストールが可能な環境であれば tr コマンドや nkf コマンドの代わりに uconv を使うと良いでしょう。文字コード変換の iconv コマンドで有名な ICU プロジェクトのコマンドなので多くの POSIX に準拠している環境に移植されており、一般的なパッケージ管理システムからインストールできるはずです。

tr コマンドの問題点

# macOS (BSD版) (注意 「あ-ん」では全てのひらがなが変換されるわけではありません)
$ echo ぁあいうえおゔ | tr "あ-ん" "ア-ン"
ぁアイウエオゔ

# Linux (GNU版) (Unicode 非対応)
$ echo ぁあいうえおゔ | tr "あ-ん" "ア-ン"
]��]�]]��]��]��]��]]�

uconv コマンドの例

結構いろんな変換ができます。この記事ではすべてを紹介しているわけではないので、-x オプションで指定する変換規則 (Transliteration) についての詳細は「Transforms | ICU Documentation」を参照してください。

文字コードの変換

uconviconvnkf と同じように文字コードの変換を行うことができます。文字コードの変換として使う場合、オプションは iconv と互換性があるように設計されており簡単に置き換えることができます。もちろん Shift JIS や EUC-JP だけではなく、世界中の文字コードに対応しています。uconv -l で対応している文字コード一覧を出力することができます。

$ echo あいう | uconv -f UTF-8 -t SHIFT_JIS | nkf --guess
Shift_JIS (LF)

$ uconv -l # 対応している文字コード一覧を出力
(大量にあるので省略)

注意 nkf --guess は変換後の文字コードの確認のためだけに使用しています。

半角を全角に変換

$ echo アイウエオabcde | uconv -x "Halfwidth-Fullwidth"
アイウエオabcde

全角を半角に変換

$ echo アイウエオ | uconv -x "Fullwidth-Halfwidth"
アイウエオ

カタカナのみを半角から全角に変換

Unicode プロパティが使用できます。

$ echo アイウエオabcde | uconv -x "\p{katakana} Halfwidth-Fullwidth"
アイウエオabcde

大文字に変換

$ echo abcde | uconv -x "upper"
ABCDE

ひらがなをカタカナに変換

$ echo あいうえお | uconv -x katakana
アイウエオ

カタカナをひらがなに変換

$ echo アイウエオ | uconv -x hiragana
あいうえお

指定した範囲のみの変換

$ echo ABCDEABCDE | uconv -x "[A-C] lower"
abcDEabcDE

複数の変換を一度に行う

大文字変換⇒全角変換といった一連の変換も一コマンドで実行できる。

注意 単純に複数の変換を繋げられるわけではないようです。何をどう組み合わせられるのかよく分かっていません。

$ echo abcde | uconv -x "upper; Halfwidth-Fullwidth"
ABCDE

特定の文字を変換

$ echo abc | uconv -x 'b>ビー'
aビーc

文字削除(tr -d 相当)

$ echo abcde | uconv -x '[b-d] remove'
ae

以下の方法でも可能

$ echo abcde | uconv -x '[b-d] >;'
ae

最初の一文字だけ大文字化

echo abc | uconv -x 'title'
Abc

以下の方法でも可能

echo abc | uconv -x '^(.) > &upper($1)'
Abc

文字単位の変換

文字の順番を入れ替え、さらに片方だけ大文字化しています。

$ echo abcd | uconv -x '(.)(.) > &upper($2)$1'
BaDc

ローマ字変換

$ echo aiueo | uconv -x hiragana
あいうえお

制御文字を名前で出力

$ printf 'a\tb' | uconv -x '\p{Cc} any-name'
a\N{<control-0009>}b%

注意 最後の % は出力が改行で終わらない場合に zsh がそれを知らせるためにつけているものです。

Unicode 正規化 (NFD, NFC, NFKD, NFKC)

Unicode 正規化 を行うことが出来ます。

$ echo ガガ | uconv -x NFD # ef bd b6   ef be 9e   e3 82 ab   e3 82 99
ガガ
$ echo ガガ | uconv -x NFC # ef bd b6   ef be 9e   e3 82 ac
ガガ
$ echo ガガ | uconv -x NFKD # e3 82 ab   e3 82 99   e3 82 ab   e3 82 99
ガガ
$ echo ガガ | uconv -x NFKC # e3 82 ac   e3 82 ac
ガガ

と言いたいところなのですが、2023-06-15: ICU 73.2 時点で(おそらく)バグにより NFC / NFKC が機能しない文字があります。

$ # 「が」はNFCできる
$ printf が | uniname
character  byte       UTF-32   encoded as     glyph   name
        0          0  00304C   E3 81 8C       が      HIRAGANA LETTER GA
$ printf が | uconv -x nfd | uconv -x nfc | uniname
character  byte       UTF-32   encoded as     glyph   name
        0          0  00304C   E3 81 8C       が      HIRAGANA LETTER GA

$ # 「ガ」はNFCできない
$ printf ガ | uniname
character  byte       UTF-32   encoded as     glyph   name
        0          0  0030AC   E3 82 AC       ガ      KATAKANA LETTER GA
$ printf ガ | uconv -x nfd | uconv -x nfc | uniname
character  byte       UTF-32   encoded as     glyph   name
        0          0  0030AB   E3 82 AB       カ      KATAKANA LETTER KA
        1          3  003099   E3 82 99       ゙      COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK

カタカナの濁点の場合がだめとか言うわけではなく、特定の文字だけ NFC / NFKC が機能しないので謎です。以下の [ ] の文字が正しく機能しない文字です。

がぎぐげござじずぜぞだぢづで[ど][ば][ぱ]びぴぶぷ[べ][ぺ]ぼぽゔゞ
[ガ][ギ][グ]ゲゴザジ[ズ][ゼ][ゾ][ダ]ヂヅデドバパビピブプベペボポヴ[ヷ]ヸヹヺ[ヾ]

NFC / NFKC を使いたい場合は、Perl か Ruby を使うのがおすすめです。どちら標準モジュールで動作し、短く書くことが出来ます。

$ printf ガ | uconv -x nfd | perl -MUnicode::Normalize -CS -pe '$_=NFC($_)' | uniname
character  byte       UTF-32   encoded as     glyph   name
        0          0  0030AC   E3 82 AC       ガ      KATAKANA LETTER GA

$ printf ガ | uconv -x nfd | ruby -pe '$_.unicode_normalize!(:nfc)' | uniname
character  byte       UTF-32   encoded as     glyph   name
        0          0  0030AC   E3 82 AC       ガ      KATAKANA LETTER GA

インストール方法

macOS

brew install icu4c

.zshrc などで環境変数 PATH を設定する

export PATH="/usr/local/opt/icu4c/bin:$PATH"

Debian

sudo apt install icu-devtools

RedHat

sudo yum install icu

参考リンク

7
6
2

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
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?