質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

2回答

1691閲覧

Goのスクリプトの出力を、Powershell経由でテキスト書き出した時、日本語が化けないようにしたい。

Takeharu_Yabe

総合スコア7

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2019/07/26 08:42

前提・実現したいこと

Windows10環境です。

Go言語で書いたスクリプトの出力をPowershell経由でテキストに書き出すと、日本語が文字化けします。

スクリプトの内容は、
コマンドプロンプトのTreeコマンドのように、指定ディレクトリ内のファイル名を列挙していくものです。

WindowsのPowershellから下記のコマンドで実行すると、書き出されたテキストファイルで日本語が文字化けします。

go run "tree.go" . > _tree.txt

utf16LittleEndianで書き出されます。

でも、単にPowershellのウィンドウに結果を表示するだけなら、文字化けしません。
Powershellの$OutputEncoding は US-ASCII です。

また、Dosのコマンドプロンプトから実行すると、化けません。utf8で書き出されます。
コマンドプロンプトは、コード ページ: 932

goのスクリプトファイルのテキストエンコーディングは、utf8 です。

日本語が文字化けしないように書き出す方法をご教授ください。
よろしくお願いします。

発生している問題

// 日本語の文字化け Abstract 54444_繝輔Λ繝・す繝・繝峨ヮ繧、繧コL_RT.jpg 54444_繝輔Λ繝・す繝・繝峨ヮ繧、繧コM_RT.jpg 54568_繝「繝弱ヨ繝シ繝ウ繝舌Φ繝悶・D_RT.jpg 54568_繝「繝弱ヨ繝シ繝ウ繝舌Φ繝悶・L_RT.jpg 54595_繧ウ繝シ繝繝ゥ繧、繝ウD_RT.jpg 54595_繧ウ繝シ繝繝ゥ繧、繝ウL_RT.jpg 54595_繧ウ繝シ繝繝ゥ繧、繝ウM_RT.jpg 54624_繧ォ繝・ユ繧、繝ウ繧ー繧ィ繝ウ繝懊せD_RT.jpg 54624_繧ォ繝・ユ繧、繝ウ繧ー繧ィ繝ウ繝懊せL_RT.jpg 54624_繧ォ繝・ユ繧、繝ウ繧ー繧ィ繝ウ繝懊せM_RT.jpg 54625_繝槭・繝悶Ν繝輔Ο繧ヲD_RT.jpg 54625_繝槭・繝悶Ν繝輔Ο繧ヲL_RT.jpg 54625_繝槭・繝悶Ν繝輔Ο繧ヲM_RT.jpg

該当のソースコード

Golang

1 2package main 3 4import ( 5 "fmt" 6 "os" 7 "path/filepath" 8) 9 10func tree(_path string, level int) { 11 pattern := _path + "/*" 12 files, err := filepath.Glob(pattern) 13 if err != nil { 14 panic(err) 15 } 16 17 for _, f := range files { 18 tab := "" 19 20 for i := 0; i < level; i++ { 21 tab += "\t" 22 } 23 24 fileInfo, _ := os.Stat(f) 25 fmt.Printf("%s%s\n", tab, filepath.Base(f)) 26 27 if fileInfo.IsDir() { 28 tree(f, level+1) 29 } 30 } 31} 32 33func main() { 34 if len(os.Args) == 2 { 35 targetDir := os.Args[1] 36 tree(targetDir, 0) 37 } 38} 39 40

試したこと

Powershellでテキストエンコーディングを指定しても文字化けします。

| Out-File $outfile -Encoding UTF8
$OutputEncoding = [Console]::OutputEncoding go run "C:\Users\Takeharu\go\src\my_projects\tree0.go" . | Out-File _tree2.txt -Encoding UTF8

補足情報(FW/ツールのバージョンなど)

Windows10
go1.12.7 windows/amd64
PSVersion 5.1.17763.592

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

PowerShell はバージョンによってエンコーディングの方法が違うので注意が必要です。

この場合は 6.0 未満だと思うので、BOM 無しの UTF8 で保存するコマンドレットはありません。

https://docs.microsoft.com/ja-jp/dotnet/api/system.io.file.writealllines?view=netframework-4.8 を使ってください。

BOM 無しの Encoding は https://docs.microsoft.com/ja-jp/dotnet/api/system.text.utf8encoding.-ctor?view=netframework-4.8#System_Text_UTF8Encoding__ctor_System_Boolean_ を false で作ってください。

追記

ps1

1$encoding = New-Object System.Text.UTF8Encoding $false 2[System.IO.File]::WriteAllLines($outfile, (go run "tree.go"), $encoding)

なお $outfile をフルパスで指定しなければ思わぬところに保存されるかもしれません。そうでない場合は Convert-Path を使ってフルパスに直してください。

投稿2019/07/26 23:42

編集2019/07/27 00:40
Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Takeharu_Yabe

2019/07/27 10:39

ありがとうございます。 BOMなしUTF8出力出来ました。 ただ、やはり日本語は化けてしまいます...。 そこで同じことをPython3でやってみたところ、日本語をちゃんとテキスト出力出来ました。 どうもスクリプト内部で扱われているテキストのエンコーディングのほうが重要なようです。 Atomで書いているのですが、GoはPrint結果が日本語でちゃんと表示されますが、 Pythonは文字化けします。 でも、シェルを通すと、Goは文字化け、Pythonはちゃんと出ます。 ややこしいです...。
Zuishin

2019/07/27 10:45

読み込み時点で UTF8 として読み込んでいないか、確認の仕方が間違っているということはありませんか?
Takeharu_Yabe

2019/07/27 22:30

書き出されたテキストファイルは、Emeditorで開いています。 エンコーディングの判定はEmeditor任せで、エンコーディング名がウィンドウ下に表示されます。 Pythonからのテキストも、Goからのテキストも同じように開いているので、条件は一緒です。
Zuishin

2019/07/27 22:33 編集

化けているということは EmEditor による自動判定が間違っているということです。UTF8 を指定して開きなおしてください。
Takeharu_Yabe

2019/07/28 04:59

Emeditorはちゃんと開いてくれていると思います。 同じテキストファイルをAtomで開いてもメモ帳で開いても同じ結果です。 Powershellにちゃんと表示出来るのに、書き出すと文字化けというのがわかりません...。
Zuishin

2019/07/28 05:02

ちょっとその文字化けが再現する最小のコードとデータを作ってください。データは UTF8 のテキストファイルという設定でお願いします。
Takeharu_Yabe

2019/07/28 05:17

最小にしたものが(Goのスクリプト)が、上の"該当のソースコード"です。 Powershell上のコマンドは以下です。 ``` $outfile = "./_tree2.txt" [System.IO.File]::WriteAllLines($outfile, (go run "tree.go" . ), (New-Object System.Text.UTF8Encoding $false) ) ``` データはありません。 ディレクトリツリーをトレースして名前を取っています。 それをテキストファイルに保存しようとしています。 テストに使ったディレクトリには、 以下のような名前のファイルが入っています。 -------------------------------------------------------------- Abstract 54444_フラッシュドノイズL_RT.jpg 54444_フラッシュドノイズM_RT.jpg 54568_モノトーンバンブーD_RT.jpg 54568_モノトーンバンブーL_RT.jpg 54595_コームラインD_RT.jpg 54595_コームラインL_RT.jpg 54595_コームラインM_RT.jpg 54624_カッテイングエンボスD_RT.jpg -------------------------------------------------------------- ちなみにPython3版は以下です。 ``` from pathlib import Path import sys def tree(path=None, level=0): p = Path(path) if p.exists(): ff = sorted( list(p.glob('*')) ) last = len(ff)-1 for i,f in enumerate(ff): newline = '' if i == last: newline = '\n' print('{0}{1}'.format( '\t' * level, f.name.split('\').pop() ) ) if f.is_dir(): tree(f, level + 1) if __name__ == '__main__': args = sys.argv if 2 <= len(args): tree(args[1], 0) ``` こちらはテキストファイルに保存しても日本語は化けません。 違いはなんでしょうか
Zuishin

2019/07/28 09:08

UTF8 の文字列を出力する実行ファイルを作って試してみました。その場合、表示も化けました。 もしかすると、go は出力がコンソール(画面)の場合に限り、コードページを合わせるようになっているのかもしれません。その場合は、パイプラインへ出力する場合とコードページが違うので、そこで齟齬が生じます。 パイプラインですが、PowerShell のパイプラインは特別で、バイナリデータではなくオブジェクトが流れます。 go など、コマンドレット以外のコマンドの場合、パイプラインに流れるのはバイナリデータですが、これを PowerShell はシフト JIS の文字列であると解釈し、string に変換します。 go が流すのはシフト JIS ではなく UTF8 なので、ここで文字化けが生じることになります。 ただし、出力先が画面の場合に限り、go はシフト JIS のデータを流すというのが私の立てた仮説です。 そうすると、解決法はいくつかありますが、スクリプトを作らなければならないなど面倒です。しかし今回の場合、UTF8 の文字列を UTF8 のファイルにしているだけなので、PowerShell のパイプラインを通してデータを何度も変換するのは無駄な気がします。そこで、手っ取り早く cmd を呼び出すのが結局のところは一番効率がいいのではないかと思います。 cmd /c 'go run "tree.go" . > ./_tree2.txt'
Takeharu_Yabe

2019/07/29 04:05

お時間割いていただきありがとうございます。 そういう仕様というのなら仕方ないのかもしれないですね...。 Goの勉強がてらはじめたことですが、Pythonを勉強したとき同様、日本語には苦労します...。 最終的にProfileに関数として保存して、短いコマンド名で使えるようにしようと思っていたのですが、 コマンドプロンプトのほうがうまく行くというなら、 バッチファイルにドラッグ&ドロップする使い方にしたほうが簡単かもしれません。 Powershell、なかなか使いこなせません...。
guest

0

PowerShellはデフォルトの文字コードがShiftJISとなってます。
だもんで、ShiftJISにエンコードしてみては。

あるいは、PowerShellの文字コードをUTF8に予め設定しておく、というテですが

投稿2019/07/26 09:03

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Takeharu_Yabe

2019/07/26 22:42

$OutputEncoding = [Console]::OutputEncoding go run "tree.go" . | Out-File -Encoding default _tree1.txt として、ShiftJISに書き出してみましたが、やっぱり文字化けします。
y_waiwai

2019/07/26 23:52

ファイルに書き出すという話なら、どうやらPowerShellでは(デフォルトでは)BOM付きUTF8しか認識しないようです ということで、 https://blog.shibata.tech/entry/2016/10/02/154329 ここらへんは参考になるでしょうか
Takeharu_Yabe

2019/07/27 10:46

``` go run "tree.go" . | Out-String | % { [Text.Encoding]::UTF8.GetBytes($_) } | Set-Content -Path ".\BOMなしUTF8なファイル.txt" -Encoding Byte ``` としてみたのですが、文字化けは直りません。 ややこしいですね...。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問