私の新しい Arch インストールでは、perl
Unicode がうまく動作しないようです。たとえば、次の入力ファイルがあるとします。
ελα ρε
王小红
このコマンドを実行すると、各行の最後の 2 文字が返されます。
$ perl -CIO -pe 's/.*(..)$/$1/' file
ε
º¢
しかし、上記のように意味不明な結果になります。正しい出力は次のとおりです。
ρε
小红
gnome-terminator
以下の両方とも期待どおりに動作するため、私のターミナル ( ) は UTF-8 をサポートしていることがわかります。
$ cat file
ελα ρε
王小红
$ perl -pe '' file
ελα ρε
王小红
残念ながら、 がなければ-CIO
、perl
ファイルも正しく処理されません。
$ perl -pe 's/.*(..)$/$1/' file
ε
��
これはロケールの問題でもないはずです:
$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
いくつかの Perl パッケージをインストールする必要があると思いますが、どれをインストールすればよいかわかりません。関連情報:
$ perl --version | grep subversion
This is perl 5, version 22, subversion 0 (v5.22.0) built for x86_64-linux-thread-multi
$ pacman -Qs unicode
local/fribidi 0.19.7-1
A Free Implementation of the Unicode Bidirectional Algorithm
local/icu 55.1-1
International Components for Unicode library
local/libunistring 0.9.6-1
Library for manipulating Unicode strings and C strings
local/perl 5.22.0-1 (base)
A highly capable, feature-rich programming language
local/perl-unicode-stringprep 1.105-1
Preparation of Internationalized Strings (RFC 3454)
local/perl-unicode-utf8simple 1.06-5
Conversions to/from UTF8 from/to characterse
local/ttf-arphic-uming 0.2.20080216.1-5
CJK Unicode font Ming style
Perl インストールを Unicode でうまく動作させるにはどうすればよいですか?
答え1
あなたが説明している問題は、私がテストしたシステムでの標準的な動作です。stdinと stdout に影響するI
ためO
、次のようにすると動作するはずです。
→ cat data | perl -CIO -pe 's/.*(..)$/$1/'
ρε
小红
一方、これはそうではないかもしれません:
→ perl -CIO -pe 's/.*(..)$/$1/' data
ε
º¢
があるさらに2つのオプションperl -C
望ましい動作を生成します。
i 8 UTF-8 is the default PerlIO layer for input streams
o 16 UTF-8 is the default PerlIO layer for output streams
これは基本的に、Perl に対してファイルオープンフォームを使用するように指示しています。
open(F, "<:utf8", "data");
または、perl -CSD
の省略形であるperl -CIOEio
S 7 I + O + E
D 24 i + o
そうすると
→ perl -CSD -pe 's/.*(..)$/$1/' data
ρε
小红
PERLIO
環境変数が設定され、含まれている場合は、:utf8
この動作も有効になります。
のデフォルトの動作は、perl
configure/compile時に変更できないようです(以下のcuonglmコメント)。Archは確かにそうではありません。何も設定しません。Debian Perl パッケージがデフォルトの動作を変更するとは思えません。
答え2
それはシステムの問題ではなく、それperl
自体の問題です。
-CIO
3 つの定義済みファイルハンドルのうち 2 つでSTDIN
ある と のみに UTF-8 エンコーディングを設定します( にも設定されています) 。STDOUT
perl
-E
STDERR
使用する場合:
perl -CIO -pe 's/.*(..)$/$1/' file
perl
<>
ファイル処理にはダイヤモンド演算子を使用します。ダイヤモンド演算子<>
が使用されるようになったのはopen (引数が 2 つの形式)STDIN
コマンドラインから各ファイルに対して新しいファイルハンドルを作成すると、これらのファイルハンドルは、およびで設定した UTF-8 エンコーディングの影響を受けませんSTDOUT
。
したがって、ファイルの内容をperl
標準入力経由で渡すことができ、動作します。
perl -CIO -pe 's/.*(..)$/$1/' <file
その他のオプションについては、@マットの回答。
perl
デフォルトのエンコーディング レイヤーにロケールを使用する場合は、次を使用できます。
perl -Mopen=:locale -pe 's/.*(..)$/$1/' file
PERLIO
エンコードレイヤーの設定に使用する場合は、:encoding(uf8)
代わりに使用する:utf8
。
使用すると:utf8
エンコード手順がスキップされ、無効な UTF-8 バイト シーケンスを読み取るときに問題が発生し、セキュリティ上の問題が発生する可能性があります。