🐍

PowerShellからPythonのchardetを使って文字コードを判定

2024/04/03に公開

概要

こちらの記事でPowerShellのみを使用し文字コードを判定するFunctionを作成しましたが、
判定できる文字コードに限りがありました。

そんな課題を改善しようと今回は、PowerShellからPythonスクリプトを呼び出し、
Pythonのchardetライブラリを使用する事で、より広範囲に文字コードの判定が可能なFunctionを作成しました。

この記事のターゲット

  • Windows ユーザーの方
  • PowerShell ユーザーの方
  • PowerShell から Pythonスクリプトを実行したい方
  • Windowsでより詳細な文字コードを判定したい方

環境

Windows OS

Windows 10 Pro環境

Get-WmiObjectコマンド
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

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 -VVは大文字。

Pythonのバージョン
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 を導入してください。

https://www.microsoft.com/store/productId/9NCVDN91XZQP?ocid=pdpshare

コマンドで「Python」をインストール

  1. Microsoft Store から「アプリ インストーラー」をインストール
    コマンドでPythonをインストールする為、アプリ インストーラー のインストールを行います。
    (このMS Store アプリはGUI操作でインストールする必要あり。)
     
    このアプリをインストールするとPowerShell、またはコマンドプロンプト上からwingetコマンドが実行できます。
    次は、このwingetコマンドを使ってPython 3.12をインストール。

  2. 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内にあるコードの修正が必要です。

Get-PyEncoding
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
    }
}

参考情報

https://chardet.readthedocs.io/en/latest/
https://github.com/chardet/chardet/tree/main

まとめ

  • Windowsの機能だと判定できる文字コードの対応範囲は狭いがPythonを導入する事によって解決できた!
  • 意外と簡単にPowerShellからPythonスクリプトを実行できたので、今後は違う用途でPythonスクリプトを作成してみたい!

関連記事

https://haretokidoki-blog.com/pasocon_powershell-startup/
https://zenn.dev/haretokidoki/articles/7e6924ff0cc960
https://zenn.dev/haretokidoki/articles/fb6830f9155de5

GitHubで編集を提案

Discussion