困ったこと
マルチバイト文字を単純にcut
しようとすると、文字の途中のバイトで切れてしまう。
### ひらがなは3バイト
$ printf あ | wc -c
3
$ printf あいうえお | wc -c
15
### 先頭4バイトを表示 -> `い`が途中のバイトで切れる
$ printf あい | cut -b-4
あ�
以下に解決方法を示す。
なお、普通の日本語の文章なら動作すると思うが、サロゲートペアとかで正しく動くかは不明。
先頭の3文字を抽出
$ printf aあbいcうdえeお | grep -o '^.\{,3\}'
aあb
$ printf aあbいcうdえeお | awk -F '' '{print $1$2$3}'
aあb
一旦UTF-32等の固定長の文字コードに変換した後に切り出す方法もあるが、シェルスクリプトで実現するのは難しそう。
日本語2文字幅、ASCII 1文字幅としてカウントする
### 3文字幅抽出
$ printf 'aあbいcうdえeお' | awk -F '' '{for(i=1;i<=NF;i++){w+=2**($i!~/[\x00-\x7f]/);if(w>WIDTH){break}printf $i}}{printf "\n";w=0}' WIDTH=3
aあ
### 4文字幅抽出
$ printf 'aあbいcうdえeお' | awk -F '' '{for(i=1;i<=NF;i++){w+=2**($i!~/[\x00-\x7f]/);if(w>WIDTH){break}printf $i}}{printf "\n";w=0}' WIDTH=4
aあb
### 5文字幅抽出 (`い`を入れると6文字幅なので`い`はカット)
$ printf 'aあbいcうdえeお' | awk -F '' '{for(i=1;i<=NF;i++){w+=2**($i!~/[\x00-\x7f]/);if(w>WIDTH){break}printf $i}}{printf "\n";w=0}' WIDTH=5
aあb
### 6文字幅抽出
$ printf 'aあbいcうdえeお' | awk -F '' '{for(i=1;i<=NF;i++){w+=2**($i!~/[\x00-\x7f]/);if(w>WIDTH){break}printf $i}}{printf "\n";w=0}' WIDTH=6
aあbい