PowerShellからPythonのchardetを使って文字コードを判定
概要
こちらの記事でPowerShellのみを使用し文字コードを判定するFunctionを作成しましたが、
判定できる文字コードに限りがありました。
そんな課題を改善しようと今回は、PowerShellからPythonスクリプトを呼び出し、
Pythonのchardetライブラリを使用する事で、より広範囲に文字コードの判定が可能なFunctionを作成しました。
この記事のターゲット
- Windows ユーザーの方
- PowerShell ユーザーの方
- PowerShell から Pythonスクリプトを実行したい方
- Windowsでより詳細な文字コードを判定したい方
環境
Windows OS
Windows 10 Pro環境
PS C:\Users\"ユーザー名"> Get-CimInstance CIM_OperatingSystem
SystemDirectory Organization BuildNumber RegisteredUser SerialNumber Version
--------------- ------------ ----------- -------------- ------------ -------
C:\WINDOWS\system32 19045 XXXXX 00000-00000-00000-AAAAA 10.0.19045
^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^
↑マスク ↑マスク
PS C:\Users\"ユーザー名">
-
参考記事:PowerShell Core ではGet-WmiObjectからGet-CimInstanceに変更
https://www.vwnet.jp/windows/PowerShell/2021061301/PowerShellCore6xWMI.htm -
参考記事:Win32_OperatingSystem クラスは CIM_OperatingSystem に変更
https://learn.microsoft.com/ja-jp/windows/win32/cimwin32prov/cim-operatingsystem
PowerShell
PS C:\Users\"ユーザー名"> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.4170
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.4170
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PS C:\Users\"ユーザー名">
Python
次項で説明しているPythonのインストール後に実行可能なコマンド。
なお、python -V
のV
は大文字。
PS C:\Users\"ユーザー名"> python -V
Python 3.12.2
PS C:\Users\"ユーザー名">
事前作業「Python」のインストール
Pythonスクリプトを実行するためにはWindows OS に Python をインストールする必要があります。
直接、Microsoft Store を起動してGUI操作でインストールする方法でも問題ありませんが、
今回はなるべくコマンドを使った方法でインストールしてみようと思います。
コマンドではなく普通にMicrosoft Sotre からGUI操作でインストールしたい方は、こちらのリンクから Python 3.12 を導入してください。
コマンドで「Python」をインストール
-
Microsoft Store から「アプリ インストーラー」をインストール
コマンドでPythonをインストールする為、アプリ インストーラー のインストールを行います。
(このMS Store アプリはGUI操作でインストールする必要あり。)
このアプリをインストールするとPowerShell、またはコマンドプロンプト上からwingetコマンドが実行できます。
次は、このwingetコマンドを使ってPython 3.12をインストール。 -
wingetコマンドでMicrosoft Store アプリ「Python 3.12」をインストール
-
winget search コマンドでアプリを検索
コピー用winget search "python 3" --source msstore
wingetコマンドで名前に"python 3"を含むアプリを探すPS D:\Downloads> winget search "python 3" --source msstore 名前 ID バージョン ----------------------------------- Python 3.12 9NCVDN91XZQP Unknown Python 3.11 9NRWMJP3717K Unknown Python 3.10 9PJPW5LDXLZ5 Unknown Python 3.7 9NJ46SX7X90P Unknown Python 3.9 9P7QFQMJRFP7 Unknown Python 3.8 9MSSZTT1N39L Unknown PS D:\Downloads>
➡ 今回は「名前:
Python 3.12
, ID:9NCVDN91XZQP
」をインストールします。 -
winget install コマンド で Python 3.12 をインストール
コピー用winget install --id=9NCVDN91XZQP -e --source msstore
winget install で Python 3.12 をインストールPS D:\Downloads> winget install --id=9NCVDN91XZQP -e --source msstore 見つかりました Python 3.12 [9NCVDN91XZQP] バージョン Unknown このパッケージは Microsoft Store から提供されています。winget は、現在のユーザーに代わって Microsoft Store からパッケー ジを取得する必要がある場合があります。 契約の対象 Python 3.12 [9NCVDN91XZQP] バージョン Unknown バージョン: Unknown 公開元: Python Software Foundation 発行元 URL: https://www.python.org/ 発行元のサポート URL: https://www.python.org/doc/ 説明: Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python’s elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms. The Python interpreter and the extensive standard library are freely available in source or binary form for all major platforms from the Python web site, https://www.python.org/, and may be freely distributed. The same site also contains distributions of and pointers to many free third party Python modules, programs and tools, and additional documentation. The Python interpreter is easily extended with new functions and data types implemented in C or C++ (or other languages callable from C). Python is also suitable as an extension language for customizable applications. ライセンス: https://docs.python.org/3.12/license.html プライバシー URL: https://www.python.org/privacy 著作権: (c) Python Software Foundation 契約: Category: Developer tools Pricing: Free Free Trial: No Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction Seizure Warning: https://aka.ms/microsoft-store-seizure-warning Store License Terms: https://aka.ms/microsoft-store-license 発行元は、お客様がインストール前に上記の情報を表示し、契約に同意することを必要としています。 使用条件に同意しますか? [Y] はい [N] いいえ: y パッケージのインストールを開始しています... ██████████████████████████████ 100% インストールが完了しました PS D:\Downloads>
➡ これでお手物のWindows OSにPython環境ができました。
-
自作したFunctionのコードを紹介
ここで紹介するFunctionを実行するとPythonのchardatを使って文字コードを判定します。
PythonスクリプトはPowerShellプロファイル($PROFILE
)と同じ階層に専用のフォルダー「user-defined-py
」を作成し、
そのフォルダー内にPythonスクリプトを保存する仕組みとなっています。
私のPowerShell 5.1 環境 では $PROFILE
が「D:\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
」となるため、
Pythonスクリプトの保存先は「D:\Documents\WindowsPowerShell\user-defined-py\chardet_runner.py
」。
ちなみにPowerShell Coreなどバージョンが違うと、PowerShellプロファイルの格納先が異なるので注意!
私のPowerShell 7.4 環境(Core) の$PROFILE
は「D:\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
」です。
なお、PythonスクリプトのソースコードはPowerShellのFunction内に定数として定義。
実行するPythonのコードを変更したい場合は、保存済みの chardet_runner.py
を手動で削除し、Function内にあるコードの修正が必要です。
Function Get-PyEncoding {
Param (
[Parameter(Mandatory=$true)][System.String]$targetfile
)
# python インストール確認
if (-Not(Get-Command 'python' -ErrorAction SilentlyContinue)) {
Write-Host 'Python is not install.' -ForegroundColor Red
return
}
# 存在チェック
if (-Not(Test-Path $targetfile)) {
Write-Host "[$targetfile] does not exist." -ForegroundColor Red
return
}
# 絶対パスに変換
[System.String]$fullpath_targetfile = (Convert-Path $targetfile)
# データ種類のチェック
if (-Not(Test-Path $fullpath_targetfile -PathType Leaf)) {
Write-Host "[$fullpath_targetfile] is not a file." -ForegroundColor Red
return
}
# Pythonスクリプトのコード
[System.String[]]$py_source =
@"
import subprocess
import sys
# chardet がインストールされていない場合はインストールしてからインポート
try:
import chardet
except ImportError:
subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'chardet', '--user'])
import chardet
# 文字コードを判定するFunction
def determine_encoding(file_path):
with open(file_path, 'rb') as file:
raw_data = file.read()
result = chardet.detect(raw_data)
print(f"Detected encoding for [{file_path}] is {result['encoding']} with {result['confidence']*100}% confidence.")
# コマンドラインの引数を取得
file_path = sys.argv[1]
# 対象ファイルの文字列を判定
determine_encoding(file_path)
"@ -split "`r`n"
# Pythonスクリプトの準備
# Pythonスクリプトを格納するフォルダーがない場合は、新規作成
[System.String]$pyfolder_path = "$PROFILE\..\user-defined-py"
if (-Not(Test-Path $pyfolder_path)) {
New-Item -Path $pyfolder_path -ItemType 'directory' -Force > $null
}
$pyfolder_path = (Convert-Path $pyfolder_path)
# 今回実行するPythonスクリプトがない場合は、新規作成
[System.String]$pyscript_path = "$pyfolder_path\chardet_runner.py"
if (-Not(Test-Path $pyscript_path)) {
$utf8Encoding = New-Object System.Text.UTF8Encoding
[System.IO.File]::WriteAllText($pyscript_path, $py_source, $utf8Encoding)
}
# Pythonスクリプトの実行
try {
python $pyscript_path $fullpath_targetfile
}
catch {
Write-Host 'Python script execution error.'
return
}
}
参考情報
まとめ
- Windowsの機能だと判定できる文字コードの対応範囲は狭いがPythonを導入する事によって解決できた!
- 意外と簡単にPowerShellからPythonスクリプトを実行できたので、今後は違う用途でPythonスクリプトを作成してみたい!
関連記事
Discussion