0
0

More than 1 year has passed since last update.

WSLにShift_JISを渡す方法:PowerShellの意外な使い方

Last updated at Posted at 2022-02-13

はじめに

新たに作るテキストファイルは、BOMなしのUTF-8にしていますが、時々Shift_JIS(以下SJIS)のファイルを使うことがあります。WSLを導入した直後から、何も追加インストールせずにSJISファイルをWSL側に渡す方法を見つけたので、紹介します。

結論

ポイント

  • コマンドウィンドウ(cmd)を使う
  • パイプラインに|powershell -c $inputを挟む
  • SJIS→BOMなしUTF-8変換をWindows 10標準コマンドで実現

C:>type sjis.txt | powershell -c $input | wsl grep S
SJISのテキストです。

試したこと

入力ファイル

C:>type sjis.txt
SJISのテキストです。

WSLでcatする

C:>type sjis.txt | wsl cat
SJIS̃eLXgłB

当然文字化けします。

WSLでgrepする

C:>type sjis.txt | wsl grep S
バイナリファイル (標準入力) に一致しました

門前払いで、箸にも棒にもかかりません。

WSLでcatして、リダイレクトする

C:>type sjis.txt | wsl cat >sjis_wsl_cat.txt

C:>type sjis_wsl_cat.txt
SJISのテキストです。
C:>wsl cat sjis_wsl_cat.txt
SJIS̃eLXgłB

|wsl catも何も加工していないと考えられます。

WSLで、catしてリダイレクトする

C:>type sjis.txt | wsl cat ^>sjis_wsl_cat_hat.txt

C:>type sjis_wsl_cat_hat.txt
SJISのテキストです。
C:>wsl cat sjis_wsl_cat_hat.txt
SJIS̃eLXgłB

どちらでリダイレクトしても結果は同じでした。

👍PowerShellを挟む

C:>type sjis.txt | powershell -c $input | wsl cat
SJISのテキストです。

C:>type sjis.txt | powershell -c $input | wsl grep S
SJISのテキストです。

C:>type sjis.txt | powershell -c $input | wsl grep テ
SJISのテキストです。

WSLで普通に扱えるようになりました。
PowerSHellのバッチ処理結果がUTF-8でcmdに返され、その結果を加工せずにWSLに渡していると考えられます。

👍PowerShellを挟んで、WSLでcatして、リダイレクトする

C:>type sjis.txt | powershell -c $input | wsl cat >sjis_ps_wsl_cat.txt

C:>type sjis_ps_wsl_cat.txt
SJIS縺ョ繝・く繧ケ繝医〒縺吶€・

C:>wsl cat sjis_ps_wsl_cat.txt
SJISのテキストです。

C:>wsl hd sjis_ps_wsl_cat.txt
00000000  53 4a 49 53 e3 81 ae e3  83 86 e3 82 ad e3 82 b9  |SJIS............|
00000010  e3 83 88 e3 81 a7 e3 81  99 e3 80 82 0d 0a        |..............|
0000001e

sjis_ps_wsl_cat.txtの中身は紛らわしいですが、BOMなしUTF-8のファイルになっています。

応用:SJISからUTF-8への変換バッチファイル

sjis2utf8.bat
@echo Shift_JIS to UTF-8 Converter
@setlocal
@if not defined DSTSUFFIX set DSTSUFFIX=utf8
@if "%~1" == "" goto Usage
@for %%f in (%*) do @call :conv_wsl %%f
@echo all done
@exit /b

:conv_wsl
@set DSTFILE=%~dpn1_%DSTSUFFIX%%~x1
@echo Input: %~f1
@if not exist %1 echo %1 not found!&exit /b
@echo Output:%DSTFILE%
@type %1 | powershell -c $input | wsl cat > %DSTFILE%
@echo done
@exit /b

:Usage
@echo.
@echo Usage: %~n0 'Shift-JIS_file_name'.txt
@echo.
@echo Output: 'Shift-JIS_file_name'_utf8.txt
@exit /b

まとめて変換したくなった場合には、こんなバッチファイルを書けば、ワイルドカードなどで簡単に処理できます。

WSLが使えない場合

32bitのWindows 10を使っていたり、WSLを有効化していない環境で、更にPowerSHellのスクリプトも書きたくない場合は、上記のバッチファイルで14行目を以下のワンライナーに差し替えると、WSLを使わずにBOMなしUTF-8に変換できます。

@type %1 | powershell -c "[Text.Encoding]::UTF8.GetBytes($input) | sc -Path %DSTFILE% -enc byte"

追記:WSLが使えない場合の別解

バッチファイルの冒頭にchcp 65001を追加すると、以下のワンライナーで実現できます。必要に応じて最後にchcp 932を追加してください。

@powershell -c cat %1 > %DSTFILE%

これとの対称性を考えると、wslを使う場合も、以下に差し替えた方が良いですね。こちらはコードページ932のままで使えます。

@powershell -c cat %1 | wsl cat > %DSTFILE%

確認環境

  • Windows10 Home 21H2
  • PowerShell 5.1
  • WSL1 (Ubuntu 18.04、20.04)
OS 名:                  Microsoft Windows 10 Home
OS バージョン:          10.0.19044 N/A ビルド 19044
PSVersion:              5.1.19041.1320

  NAME            STATE           VERSION
* Ubuntu-18.04    Running         1

WSLもPowerShellも初期状態で確認しています。特別な設定は必要ありませんでした。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0