元データ内容について誤解釈しており、完全に間違った回答をしていました。
失礼しました。
標準入力で受け取るのはユニコードエスケープ形式の文字列であり、これは
stdin.readline().decode("unicode-escape")
により正しくunicode
文字列に変換されます。
しかし次の出力処理 print
において、出力先がターミナル(端末)では正常に動作していますが、出力先がファイルの場合にエラーが発生しています。
その原因および対応法はfuzzball
さんの回答に示されているリンク先が正しいかと思います。
以下、以前の回答
まず、cat
コマンドは文字コードの変換はおこないません。
text
の内容が、ユニコードエスケープ(\uxxxx)されて表現(出力)されているにすぎません。
元データのエンコーディングが判っておりiconvが入っていれば、以下のように任意のエンコーディングに変換できます。
PlainText
1$ which iconv
2/home/hoge/anaconda3/bin/iconv
3$ iconv -f UTF-16LE -t UTF-8 text > utf-8.txt
4$ od -Ax -tx1z ret.txt
5000000 e3 83 ac e3 82 b6 e3 83 bc >.........< #「レザー」のUTF-8表現
6000009
元データのエンコーディングが判らない場合はchardetをインストールすることでエンコーディングを自動判別できるので、以下のようなコードで変換できます。
ただし、この手法の限界として、誤判定する可能性が多分にあります。
Python
1import sys
2import chardet
3inp = sys.stdin.readline()
4det = chardet.detect(inp)
5uni_s = inp.decode(det['encoding']) # 失敗する可能性あり
6u8_s = uni_s.encode('utf-8')
7sys.stdout.write( u8_s)
また、どうしても素のPython2.x
でやる必要があれば、以下のようなコードでも、それなりにできます。
元データを片っ端からデコード→再エンコードしてみて成功(元データと一致)したエンコーディングを採用するという手法です。
参考:
テキストファイルのエンコーディングを自動判定して処理する
Pythonにおける日本語のエンコーディングの検出について
Python
1# 任意エンコード文字列をunicode文字列に自動変換
2# https://qiita.com/zarchis/items/3258562ebc9570fa05a3
3def conv_encoding(s):
4 encs = (
5 # jis系から先に試す
6 # http://d.hatena.ne.jp/kakurasan/20100330/p1
7 'iso2022jp', 'iso2022_jp_1', 'iso2022_jp_2', 'iso2022_jp_3', 'iso2022_jp_ext',
8 'utf_8',
9 'euc_jp', 'euc_jis_2004', 'euc_jisx0213',
10 'shift_jis', 'shift_jis_2004','shift_jisx0213',
11 'latin_1', 'ascii')
12 for enc in encs:
13 try:
14 us = s.decode(enc)
15 if isinstance( us, unicode):
16 # 念のため再エンコードし一致判定
17 ds = us.encode(enc)
18 if s == ds:
19 return us,enc
20 except:
21 pass
22
23 raise LookupError
24
25import sys
26inp = sys.stdin.readline()
27(uni_s,enc) = conv_encoding(inp)
28#sys.stderr.write(enc+'\n')
29u8_s = uni_s.encode('utf-8')
30sys.stdout.write( u8_s)
WSL(Windows Subsystem for Linux)での検証結果
PlainText
1$ od -Ax -tx1z iso2022jp.txt
2000000 1b 24 42 25 6c 25 36 21 3c 1b 28 42 >.$B%l%6!<.(B<
300000c
4$ python temp.py < iso2022jp.txt > ret.txt
5iso2022jp
6od -Ax -tx1z ret.txt
7000000 e3 83 ac e3 82 b6 e3 83 bc >.........<
8000009
9
10$ od -Ax -tx1z utf8.txt
11000000 e3 83 ac e3 82 b6 e3 83 bc >.........<
12000009
13$ python temp.py < utf8.txt > ret.txt
14utf_8
15$ od -Ax -tx1z ret.txt
16000000 e3 83 ac e3 82 b6 e3 83 bc >.........<
17000009
18
19$ od -Ax -tx1z eucjp.txt
20000000 a5 ec a5 b6 a1 bc >......<
21000006
22$ python temp.py < eucjp.txt > ret.txt
23euc_jp
24$ od -Ax -tx1z ret.txt
25000000 e3 83 ac e3 82 b6 e3 83 bc >.........<
26000009
27
28$ od -Ax -tx1z sjis.txt
29000000 83 8c 83 55 81 5b >...U.[<
30000006
31$ python temp.py < sjis.txt > ret.txt
32shift_jis
33$ od -Ax -tx1z ret.txt
34000000 e3 83 ac e3 82 b6 e3 83 bc >.........<
35000009
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/01/25 07:23 編集