SSブログ

PowerShell小僧:ファイル名の一括置換(改3) [コンピューター]

前回の例
https://cheese999.blog.ss-blog.jp/2021-05-06
では、履歴ファイルの読み出しの文字コードをUTF-8固定にしていました。

読み込む前にファイルの文字コードを調べて、文字化けしない様にします。

PowerShell単体では文字コードの判定ができないので、 ReadJEncのDLLを追加します。
https://www.oqiita.com/?p=2356
https://github.com/hnx8/ReadJEnc/releases

【参考】
・PowerShellの関数の返り値って、1つじゃないみたいです。
https://blog.shibata.tech/entry/2015/07/05/114903
・ ReadJEncのDLLを使用する時、DLLから出力される要らない出力の処理が難しい。関数化する時、関数の切り口に注意必要です。

【コード】
# 関数:文字コードを表示
function myFShChrCd1{
  [String]$result = chcp
  #$result.GetType().FullName
  # ":"で分割
  [String[]]$BUF1 = $result.Split(":")
  #$BUF1.GetType().FullName
  # 2個目の文字列
  $BUF2 = $BUF1[1]
  #$BUF2.GetType().FullName
  # 空白を削除
  [String]$ChCode1 = $BUF2.Trim()
  #echo $ChCode1
  #$ChCode1.GetType().FullName
  switch ($ChCode1){
    "65001"{echo "文字コードはUTF-8(65001)です。";break}
    "932"{echo "文字コードはShift-JIS(932)です。";break}
    default{echo "文字コードは不明です。";break}
  }
}
# 関数:何も入力されなかったら、デフォルト値を返す
Function Read-HostDefault($Prompt, $Default) {
    # デフォルト値がある時のプロンプト
    if ($Default) {
        $Prompt = "$Prompt [$Default]"
    }
    # コンソール入力
    $val = Read-Host $Prompt
    # 何も入力されなかったら、デフォルト値を返す
    if($val -eq ""){
      Return $Default
    }else{
      Return $val
    }
    # ($default,$val)[[bool]$val]
}
# 関数:終了処理
Function End-Process1($CurrentPath1){
  # 現在のパス
  Write-Host "現在のパス(Get-Location)"
  Get-Location
  # 入力待ち
  $INPUT = Read-HostDefault "OK?"
  # ファイル名の一覧を表示
  Write-Host "ファイル名の一覧(Get-ChildItem)"
  Get-ChildItem
  # 入力待ち
  $INPUT = Read-HostDefault "OK?"
  # スクリプト実行前のパスに戻る
  Set-Location $CurrentPath1
  # 現在のパス
  Write-Host "現在のパス(Get-Location)"
  Get-Location
  # 入力待ち
  $INPUT = Read-HostDefault "OK?"
  # 文字コードをShift-JISに変更
  chcp 932
  # 文字コードを表示
  myFShChrCd1
}
# 関数:文字コード判別
Function myMojiCode1($Name1){
If($Name1.IndexOf("ShiftJIS") -ge 0){
   $myMojiCoding1 = "Default"
}ElseIf($Name1.IndexOf("UTF-8") -ge 0){
   $myMojiCoding1 = "UTF8"
}ElseIf($Name1.IndexOf("EUCJP") -ge 0){
   $myMojiCoding1 = -1
}ElseIf($Name1.IndexOf("ASCII") -ge 0){
   $myMojiCoding1 = "ASCII"
}Else{
   $myMojiCoding1 = -1
}
Return $myMojiCoding1
}
# メイン部分
# DLLを読み込み
[Reflection.Assembly]::LoadFile("C:\abcde\PowerShell\ReadJEnc\dll\net47\Hnx8.ReadJEnc.dll") > $null
# 文字コードをUTF-8に変更
chcp 65001
# 文字コードを表示
myFShChrCd1
# 現在のパス
$CurrentPath1 = Get-Location
Write-Host "現在のパス="$CurrentPath1
# スクリプトがある場所
$ScriptPath1 = Split-Path $MyInvocation.MyCommand.Path -Parent
Write-Host "スクリプトがある場所="$ScriptPath1
$INPUT=Read-HostDefault "OK?"
# 履歴ファイル
$HistFile1 = $ScriptPath1+"\FilePath1.txt"
# 前回実行時のファイルのあるフォルダ
if(Test-Path $HistFile1){
  # 履歴ファイルの文字コード確認
  $file=Get-Item $HistFile1
  $reader=new-object Hnx8.ReadJEnc.FileReader($file)
  [String]$ReaderName1 = $reader.Read($file).Name
  Write-Host "`$reader.Read(`$file).Name="$ReaderName1
  $myMojiCoding1 = myMojiCode1($ReaderName1)

  #If($reader.Read($file).Name.IndexOf("ShiftJIS") -ge 0){
  # $myMojiCoding1 = "Default"
  #}ElseIf($reader.Read($file).Name.IndexOf("UTF-8") -ge 0){
  # $myMojiCoding1 = "UTF8"
  #}ElseIf($reader.Read($file).Name.IndexOf("EUCJP") -ge 0){
  # $myMojiCoding1 = -1
  #}ElseIf($reader.Read($file).Name.IndexOf("ASCII") -ge 0){
  # $myMojiCoding1 = "ASCII"
  #}Else{
  # $myMojiCoding1 = -1
  #}

  Write-Host "`$myMojiCoding1="$myMojiCoding1
  If($myMojiCoding1 -eq -1){
    Write-Host "履歴ファイルの文字コードが不明です。"
    $PrevPath1=$CurrentPath1
  }Else{
  # 履歴ファイルの先頭行を読み込み
  $PrevPath1=Get-Content $HistFile1 -totalcount 1 -Encoding $myMojiCoding1
  }
}
# ファイルがあるフォルダを入力
$MyFilePath1 = Read-HostDefault "ファイルがあるフォルダ?" $PrevPath1
# フォルダが存在しない場合、終了
if(-Not(Test-Path $MyFilePath1)){
  Write-Host "フォルダが存在しません。"
  End-Process1($CurrentPath1)
  Exit
}
# ファイルがあるフォルダへ移動
cd -LiteralPath $MyFilePath1
# ファイルパスをテキストファイルに出力
$ScriptPath1 = $ScriptPath1+"\FilePath1.txt"
#Write-Host $MyFilePath1 | set-content -Path $ScriptPath1
Set-Content -Encoding UTF8 -LiteralPath $ScriptPath1 -Value $MyFilePath1
# ファイル名の一覧を表示
echo "変更前のファイル名です。"
Get-ChildItem
# 入力待ち
$INPUT = Read-HostDefault "ファイル名を変更しますか(Y/N)?" "N"
if($INPUT -ne "Y"){
  # Y以外なら、処理中止
  Write-Host "処理を中断しました。"
  End-Process1($CurrentPath1)
  exit
}
# ファイルパスの長さ
[int]$MyLength1 = $MyFilePath1.Length
Write-Host "MyLength1="$MyLength1
# ファイルパスの区切り文字"_"の位置
[int]$MyLastIndex1 = $MyFilePath1.LastIndexOf("_", $MyLength1 - 1)
Write-Host "MyLastIndex1="$MyLastIndex1
# 区切り文字"_"が見つかったか?
if($MyLastIndex1 -eq -1){
  # 区切り文字"_"が見つからない
  # ファイルパスの切り出し開始文字を最終文字から2文字目にする
  [int]$MyStart1 = $MyLength1 - 3
  #Write-Host "MyStart1="$MyStart1
  # ファイルパスの最終3文字を切り出す
  [string]$PathL3 = $MyFilePath1.Substring($MyStart1,3)
  # アンダーバーを連結
  $PathL3 += "_"
  #Write-Host $PathL3
}else{
  # 区切り文字"_"が見つかった
  # ファイルパスの切り出し開始文字
  [int]$MyStart1 = $MyLastIndex1 + 1
  # 切り出す文字数
  [int]$MyLength2 = $MyLength1 - $MyStart1
  # 切り出す文字数が10を超えたら、最終3文字のみ切り出す
  if($MyLength2 -gt 10){
    # ファイルパスの切り出し開始文字を最終文字から2文字目にする
    [int]$MyStart1 = $MyLength1 - 3
    # 切り出す文字数
    [int]$MyLength2 = 3
  }
  Write-Host "MyStart1="$MyStart1
  Write-Host "MyLength2="$MyLength2
  # ファイルパスの区切り文字"_"の次の文字から最終文字までを切り出す
  [string]$PathL3 = $MyFilePath1.Substring($MyStart1, $MyLength2)
  # アンダーバーを連結
  $PathL3 += "_"
  #Write-Host $PathL3
}
# 新しいファイル名を入力
[String]$NewFileName1 = Read-HostDefault "新しいファイル名?" $PathL3
# ファイル名の連番の開始番号を入力
[String]$StartNo = Read-HostDefault "ファイル名の連番の開始番号?" 1
# ヌル判定
# if ([String]::IsNullOrEmpty($StartNo)){
# Write-Host "開始番号に何も入力されなかったので、開始番号=1とします。"
# [string]$StartNo = "1"
# 入力待ち
# $INPUT = Read-Host "OK?"
# }
# 変換後の整数変数
[Int]$StartNo1 = 0
# 整数変換
[Bool]$Result1 = [int]::TryParse($StartNo, [ref]$StartNo1)
if($Result1 -eq $FALSE){
  Write-Host "開始番号="$StartNo" に整数以外が入力されたので終了します。"
  End-Process1($CurrentPath1)
  exit
}
# 新しいファイル名の確認
[String]$String1 = "新しいファイル名:" + $NewFileName1 + $StartNo1.tostring("000") + ".jpg でよろしいですか(Y/N)?"
$INPUT = Read-HostDefault $String1 "N"
if($INPUT -eq "Y"){
  # TMP_001.xxx, TMP_002.xxx と昇順で名前を付け替える
  ls -File | sort Name | % {$i = $StartNo1} { $Newname = "TMP_" +$i.tostring("000")+$_.extension; rename-item $_ $Newname; $i++ }
  Get-ChildItem
  # 入力待ち
  $INPUT = Read-HostDefault "OK?"
  # if ([String]::IsNullOrEmpty($INPUT)){
  # echo "INPUTはNull"
  # }else{
  # echo "INPUTはNullではない"
  # }
  # $INPUT = Read-HostDefault "OK?"
  # ファイル名のTMP_をABC_に置換する
  Get-ChildItem | Rename-Item -NewName { $_.Name -replace 'TMP_',$NewFileName1 }
  # 拡張子のjpegをjpgに置換する
  Get-ChildItem | Rename-Item -NewName { $_ -replace '\.jpeg$','.jpg' }
}else{
  echo "ファイル名の変更を中止します。"
}
End-Process1($CurrentPath1)
ヤバイぜ!(12)  コメント(2) 

ヤバイぜ! 12

コメント 2

cheese999

ヤバイぜ! ありがとうございます(^_0)ノ
by cheese999 (2021-05-08 00:40) 

cheese999

どうもS-JISの履歴ファイルを読み込むと文字化けが発生するようです。
by cheese999 (2021-05-24 03:31) 

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字(英大文字の「オー」、英小文字の「ユー」、アラビア数字の「ハチ」、アラビア数字の「イチ」、アラビア数字の「ニ」)を入力してください。

Facebook コメント

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。