タスクは次のとおりでした-行が80文字を超えないように長い行を持つテキストファイルを変換します。 長い行は、80文字以下の複数の行に分割する必要があります。 ファイルはUTF-8でエンコードされます。 UnixライクなOSでは、 foldユーティリティがこのタスクを処理することを少しGoogleで確認できます。 素晴らしい、それから我々はそれを使用します。 まず、ターミナルでいくつかのテストコマンドを実行して、管理方法を学びましょう。 coreutils 8.13を備えたDebian 7.5システムで実行されたコマンドの出力を以下に示します。 同じ結論は、 coreutils 8.22を備えたArch Linuxでも同様です。
すべてのテストコマンドを実行する場合、ロケール設定は次のとおりです。
$ locale LANG=ru_RU.UTF-8 LC_CTYPE="ru_RU.UTF-8" LC_NUMERIC="ru_RU.UTF-8" LC_TIME="ru_RU.UTF-8" LC_COLLATE="ru_RU.UTF-8" LC_MONETARY="ru_RU.UTF-8" LC_MESSAGES="ru_RU.UTF-8" LC_PAPER="ru_RU.UTF-8" LC_NAME="ru_RU.UTF-8" LC_ADDRESS="ru_RU.UTF-8" LC_TELEPHONE="ru_RU.UTF-8" LC_MEASUREMENT="ru_RU.UTF-8" LC_IDENTIFICATION="ru_RU.UTF-8" LC_ALL=ru_RU.UTF-8
何か問題がある場合は、次を実行します。
$ export LC_ALL="ru_RU.UTF-8"
テストコマンドで、文字列「abcdefghij」をそれぞれ4文字の行に分割します。
$ echo "abcdefghij" | fold -w 4 abcd efgh ij
わあ! 行「abgdejouji」:
$ echo "" | fold -w 4
そして、驚きが待っています。 「abgdejouji」の行は、それぞれ2文字の行に分割されていることがわかります。 ここでのポイントは、UTF-8でエンコードされたキリル文字は2バイトで、ラテン文字は1バイトであるということです。 foldユーティリティは、すべての文字をシングルバイトと見なし、この文字列(バイト配列)を4バイトに分割しました。 ご覧のとおり、このようなパーティションアルゴリズムは、ラテン文字に対してのみUTF-8エンコーディングで有効です。 同時に、 wcユーティリティは、文字列「abdegood」の文字数を正しくカウントします。
$ echo -n "" | wc -m 10
これは、 coreutilsパッケージのunicodeサポートが部分的に実装されており、さまざまなユーティリティのunicodeを使用した結果が予測できないことを示唆しています。
実際、このエラーは数年前に知られていました。 こことここで説明されており、開発者からの答えもありますが、残念ながら、「これはバグではなく、機能です」という状態のままです。
上記はBSDシステムには適用されません。標準のユーティリティが独自に実装されています。 FreeBSD 10システムのテストでは、Unicodeですべてが正常であることが示されました。
次に、このエラーを回避する方法について説明しましょう。 私は2つのcoreutilsの置き換えを知っています: BusyBoxとHeirloom 。 最初のオプションは、より関連性が高くシンプルなように思えたので、それを使用して松葉杖を構築する方法を示します。 同様に、他の標準ユーティリティ用の松葉杖を構築できます。
まず、 busyboxパッケージをインストールします。 Debianシステムでは、コマンド:
# apt-get install busybox
それに応じて、Arch Linuxシステムでは、次のコマンドを実行します。
# pacman -S busybox
ドキュメントによると、次のようにBusyBoxを使用できます。
$ busybox ls -l $ busybox ps $ busybox seq 1 5
つまり ユーティリティ名をbusybox実行可能ファイルにパラメータとして渡すだけです。 また、実行可能ファイルの名前を、それがサポートするコマンドの1つに変更することもできます。これは、これがコマンドであるかのように自動的に動作します。 名前は変更しませんが、名前が折り畳まれたシンボリックリンクを作成します。
# cd $(dirname $(which fold)) # mv fold fold.orig # ln -s $(which busybox) fold
その後、 foldは最もよく知られた方法で使用できます。ターミナルまたはスクリプトから呼び出します。 システム内のそのようなパッチは私には受け入れられます。 彼女が誰かを助けることができたら嬉しいです。 それまでの間、いつかcoreutilsがUnicodeを完全にサポートすることを期待しています。