はじめに
新たに作るテキストファイルは、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への変換バッチファイル
@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も初期状態で確認しています。特別な設定は必要ありませんでした。
参考