SSブログ

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

前回、
https://cheese999.blog.ss-blog.jp/2021-06-04

から、ちょっと変更したのですが、何を変更したか、忘れました。
Visual Studio Codeで、このスクリプトを開くと、次のワーニングが出ます。

【該当箇所のスクリプト】
Get-ChildItem -File *.$tmpExt1
| Sort-Object Name | ForEach-Object -Begin {$myCNT2 = $StartNo1}
-Process { $Newname = $tmpName1+$myCNT2.tostring("000")+$_.extension;
rename-item $_ $Newname; $myCNT2++ }

【ワーニングの内容】
PSUseDeclaredVarsMoreThanAssignments
The variable 'myCNT2' is assigned but never used.

これは、Visual Studio Code、もしくは、PowerShellの既知バグの様です。
https://www.gitmemory.com/issue/PowerShell/PSScriptAnalyzer/1639/776332539

【スクリプト全体】
## 定数 ##
# 文字コード変換DLL
$myDLL = "C:\abcde\PowerShell\ReadJEnc\dll\net47\Hnx8.ReadJEnc.dll"
# スクリプトがある場所
$ScriptPath1 = Split-Path $MyInvocation.MyCommand.Path -Parent
# 履歴ファイル
$HistFile1 = $ScriptPath1+"\FilePath1.txt"
# 拡張子ファイル
$ExtFile1 = $ScriptPath1+"\FileExtension1.txt"
# 関数:文字コードを表示
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"{Write-Host "Character code is UTF-8(65001).";break}
    "932"{Write-host "Character code is Shift-JIS(932).";break}
    default{Write-Host "Character code is unknown.";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
  # 入力待ち
  Read-HostDefault "OK?" > $null
  # スクリプト実行前のパスに戻る
  Write-Host "スクリプト実行前のパスに戻ります。"
  Set-Location $CurrentPath1
  # 現在のパス
  Write-Host "現在のパス(Get-Location):スクリプト実行前"
  Get-Location
  write-host "文字コードをShift-JIS(932)に変更します。"
  # 入力待ち
  Read-HostDefault "OK?" > $null
  # 文字コードを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
}
# 関数:区切り文字の次の文字から最終文字までを切り出す
Function myStrCut1($MyFilePath1,$MyLastIndex){
  # 元の文字列の長さ
  [int]$MyLength1 = $MyFilePath1.Length
  # ファイルパスの切り出し開始文字
  [int]$MyStart1 = $MyLastIndex + 1
  Write-Host "MyStart1="$MyStart1
  # 切り出す文字数
  [int]$MyLength2 = $MyLength1 - $MyStart1
  Write-Host "MyLength2="$MyLength2
  # ファイルパスの区切り文字"_"の次の文字から最終文字までを切り出す
  [string]$PathL3 = $MyFilePath1.Substring($MyStart1, $MyLength2)
  # 切り出した文字数が10文字を超えたら、10文字に切り詰める
  if($MyLength2 -gt 10){
    [int]$MyStart1 = $MyLength2 - 10
    [string]$PathL3 = $PathL3.Substring($MyStart1, 10)
  }
  # アンダーバーを連結
  $PathL3 += "_"
  # Write-Host "`$PathL3="$PathL3
  return $PathL3
}
# 関数:英数字1文字をランダムに発生(a-z,A-Z,0-9)
Function myRnd1Char($myMode1){
  if($myMode1 -eq 1){
    # 英字(a-z,A-Z)
    $myCharCode1 = Get-Random -Maximum 51 -Minimum 0
  }else{
    # 英数字(a-z,A-Z,0-9)
    $myCharCode1 = Get-Random -Maximum 61 -Minimum 0
  }
  if(($myCharCode1 -ge 0) -and ($myCharCode1 -le 25)){
    # 英字(A-Z)
    $myCharCode1 = $myCharCode1 + 65
  }elseif(($myCharCode1 -ge 26) -and ($myCharCode1 -le 51)){
    # 英字(a-z)
    $myCharCode1 = $myCharCode1 + 71
  }elseif(($myCharCode1 -ge 52) -and ($myCharCode1 -le 61)){
    # 数字(0-9)
    $myCharCode1 = $myCharCode1 - 4
  }
  $encoding_wk = [system.Text.Encoding]::GetEncoding("ASCII")
  $myChar1 = $encoding_wk.GetChars($myCharCode1)
  Return $myChar1
}
# メイン部分
# DLLを読み込み
$myDLL = Read-HostDefault "文字コード変換DLL?" $myDLL
if(-Not(Test-Path $myDLL)){
  Write-Host "文字コード変換DLLが存在しません。"
  exit
}
[Reflection.Assembly]::LoadFile($myDLL) > $null
# 拡張子ファイルを読み込み
$ExtFile1 = Read-HostDefault "拡張子ファイル?" $ExtFile1
if(-Not(Test-Path $ExtFile1)){
  Write-Host "拡張子ファイルが存在しません。"
  exit
}
# 拡張子ファイルの文字コード確認
$file=Get-Item $ExtFile1
$reader=new-object Hnx8.ReadJEnc.FileReader($file)
[String]$ReaderName1 = $reader.Read($file).Name
Write-Host "`$reader.Read(`$file).Name="$ReaderName1
$myMojiCoding1 = myMojiCode1($ReaderName1)
Write-Host "`$myMojiCoding1="$myMojiCoding1
$myLine1 = (Get-Content -LiteralPath $ExtFile1|Measure-Object -Line).Lines
Write-Host "拡張子ファイルの行数="$myLine1
If($myMojiCoding1 -eq -1){
  # 拡張子ファイルの文字コードが不明な場合
  Write-Host "拡張子ファイルの文字コードが不明です。"
  exit
}Else{
  # 拡張子ファイルの文字コードが明確な場合
  # 拡張子変数の配列宣言
  $myExt1 = @()
  # 拡張子ごとのファイル数の配列宣言
  $myExtCount1 = @()
  # 履歴ファイルを履歴変数(配列)に読み込み
  # $myExt1=Get-Content $ExtFile1 -totalcount 1 -Encoding $myMojiCoding1
  # $OutputEncoding = [console]::OutputEncoding;
  # Write-Host "`$myExt1=$myExt1"
  $myExt1=(Get-Content $ExtFile1 -Encoding $myMojiCoding1) -as [string[]]
}
# 拡張子カウンタ
$myCNT4 = 1
# 拡張子の数だけ、繰り返し
foreach ($tmpExt1 in $myExt1){
  Write-Host "`$tmpExt1("$myCNT4")="$tmpExt1
  $myCNT4++
}
# 入力待ち
Read-HostDefault "OK?" > $null
# 文字コードをUTF-8に変更
chcp 65001
# 文字コードを表示
myFShChrCd1
# 現在のパス
$CurrentPath1 = Get-Location
Write-Host "現在のパス="$CurrentPath1
Write-Host "スクリプトがある場所="$ScriptPath1
$HistFile1 = Read-HostDefault "履歴ファイル?" $HistFile1
Read-HostDefault "OK?" > $null
# 履歴変数の配列宣言
$PrevPath1 = @()
# エラーフラグをリセット
$ErrFlg1 =$FALSE
# 履歴ファイルの存在確認
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)
  Write-Host "`$myMojiCoding1="$myMojiCoding1
  $myLine1 = (Get-Content -LiteralPath $HistFile1|Measure-Object -Line).Lines
  Write-Host "履歴ファイルの行数="$myLine1
  If($myMojiCoding1 -eq -1){
    # 履歴ファイルの文字コードが不明な場合
    Write-Host "履歴ファイルの文字コードが不明です。"
    $PrevPath1 += $CurrentPath1
  }Else{
    # 履歴ファイルの文字コードが明確な場合
    # 履歴ファイルを履歴変数(配列)に読み込み
    $PrevPath1=Get-Content $HistFile1 -totalcount 1 -Encoding $myMojiCoding1
    $OutputEncoding = [console]::OutputEncoding;
    Write-Host "`$PrevPath1=$PrevPath1"
    $PrevPath1=(Get-Content $HistFile1 -Encoding $myMojiCoding1) -as [string[]]
  }
}else{
  # 履歴ファイルが存在しない場合
  Write-Host "履歴ファイルが存在しません。"
  $PrevPath1 += $CurrentPath1
}
# 履歴カウンタ
[int]$myCNT1 = 1
# 履歴の数だけ繰り返し
foreach ($MyPrev1 in $PrevPath1){
  # ファイルがあるフォルダを入力
  $MyFilePath1 = Read-HostDefault "($myCNT1/$myLine1)ファイル名変更の対象ファイルがあるフォルダ?" $MyPrev1
  if(-Not(Test-Path $MyFilePath1)){
    # フォルダが存在しない
    Write-Host "フォルダが存在しません。"
    $ErrFlg1 = $TRUE
  }else{
    # フォルダが存在する場合
    # ファイルがあるフォルダへ移動
    Set-Location -LiteralPath $MyFilePath1
    # ファイルパスをテキストファイルに出力
    if($myCNT1 -eq 1){
      # 初回は新規書き込み
      Set-Content -Encoding UTF8 -LiteralPath $HistFile1 -Value $MyFilePath1
    }else{
      # 2回目以降は追記
      Add-Content -Encoding UTF8 -LiteralPath $HistFile1 -Value $MyFilePath1
    }
    # ファイル名の一覧を表示
    Write-Host "変更前のファイル名です。"
    Get-ChildItem
    # 入力待ち
    $myINPUT1 = Read-HostDefault "ファイル名を変更しますか(Y/N)?" "N"
  }
  if(($ErrFlg1 -eq $FALSE) -and ($myINPUT1 -eq "Y")){
    # エラーフラグが偽、かつ、答えがYなら、以下実行
    # ファイルパスの長さ
    [int]$MyLength1 = $MyFilePath1.Length
    Write-Host "MyLength1="$MyLength1
    # ファイルパスの区切り文字"_"の位置
    [int]$MyLastIndex1 = $MyFilePath1.LastIndexOf("_", $MyLength1 - 1)
    Write-Host "`$MyLastIndex1="$MyLastIndex1
    # ファイルパスの区切り文字"\"の位置
    [int]$MyLastIndex2 = $MyFilePath1.LastIndexOf("`\", $MyLength1 - 1)
    Write-Host "`$MyLastIndex2=$MyLastIndex2"
    if(($MyLastIndex1 -eq -1) -And ($MyLastIndex2 -eq -1)){
      # 区切り文字"_", "\"の両方が見つからない場合
      # ファイルパスの切り出し開始文字を最終文字から2文字目にする
      $MyLastIndex2 = $MyLength1 - 3 - 1
      # ファイルパスの最終3文字を切り出す
      [string]$PathL3 = myStrCut1 $MyFilePath1 $MyLastIndex2
    }elseif(($MyLastIndex1 -ge 0) -And ($MyLastIndex2 -eq -1)){
      # 区切り文字"_"だけ見つかった場合
      # ファイルパスの最終"_"から後ろを切り出す
      [string]$PathL3 = myStrCut1 $MyFilePath1 $MyLastIndex1
    }elseif(($MyLastIndex1 -eq -1) -And ($MyLastIndex2 -ge 0)){
      # 区切り文字"\"だけ見つかった場合
      # ファイルパスの最終"\"から後ろを切り出す
      [string]$PathL3 = myStrCut1 $MyFilePath11 $MyLastIndex2
    }elseif(($MyLastIndex1 -ge 0) -And ($MyLastIndex2 -ge 0)){
      # 区切り文字"_", "\"の両方が見つかった場合
      if($MyLastIndex1 -gt $MyLastIndex2){
        # 区切り文字"_"が"\"より後ろにある場合
        # ファイルパスの最終"_"から後ろを切り出す
        [string]$PathL3 = myStrCut1 $MyFilePath1 $MyLastIndex1
      }else{
        # 区切り文字"\"が"_"より後ろにある場合
        # ファイルパスの最終"\"から後ろを切り出す
        [string]$PathL3 = myStrCut1 $MyFilePath1 $MyLastIndex2
      }
    }
    Write-Host "`$PathL3="$PathL3
    # 新しいファイル名候補の\を_に変換
    $PathL3 = $PathL3.replace("`\","_")
    # 新しいファイル名を入力
    [String]$NewFileName1 = Read-HostDefault "新しいファイル名?" $PathL3
    # 日付をファイル名に追加
    [String]$myDate1 = Get-Date -Format "yyyyMMdd"
    # 入力待ち
    $myINPUT1 = Read-HostDefault "日付($myDate1)をファイル名に追加しますか(Y/N)?" "N"
    if($myINPUT1 -eq "Y"){
      $NewFileName1 += $myDate1
      $NewFileName1 += "_"
    }
    # 曜日をファイル名に追加
    [String]$myYoubi = (Get-Date).DayOfWeek
    $myYoubi = $myYoubi.Substring(0,3)
    # 入力待ち
    $myINPUT1 = Read-HostDefault "曜日($myYoubi)をファイル名に追加しますか(Y/N)?" "N"
    if($myINPUT1 -eq "Y"){
      $NewFileName1 += $myYoubi
      $NewFileName1 += "_"
    }
    # 時刻をファイル名に追加
    # タイムゾーンを表示
    $MyTimeZone = Get-CimInstance -Class Win32_TimeZone -Namespace "Root\CIMV2"
    [int]$MyJisa = $MyTimeZone.Bias / 60
    if($MyJisa -gt 0){
      [string]$myFugou1 ="+"
    }else{
      [string]$myFugou1 =""
    }
    Write-Host "UTCとの時差="$myFugou1$MyJisa"時間"
    Write-Host "タイムゾーン:"$MyTimeZone.Caption
    [String]$myTime1 = Get-Date -Format "HHmmss"
    # 入力待ち
    $myINPUT1 = Read-HostDefault "時刻($myTime1)をファイル名に追加しますか(Y/N)?" "N"
    if($myINPUT1 -eq "Y"){
      $NewFileName1 += $myTime1
      $NewFileName1 += "_"
    }
    # ファイル名の連番の開始番号を入力
    [String]$StartNo = Read-HostDefault "ファイル名の連番の開始番号?" 1
    # ヌル判定
    # if ([String]::IsNullOrEmpty($StartNo)){
    # Write-Host "開始番号に何も入力されなかったので、開始番号=1とします。"
    # [string]$StartNo = "1"
    # 入力待ち
    # Read-HostDefault "OK?" > $null
    # }
    # 変換後の整数変数
    [Int]$StartNo1 = 0
    # 整数変換
    [Bool]$Result1 = [int]::TryParse($StartNo, [ref]$StartNo1)
    if($Result1 -eq $FALSE){
      Write-Host "開始番号="$StartNo" に整数以外が入力されたのでスキップします。"
      $ErrFlg1 = $TRUE
    }
    if($ErrFlg1 -eq $FALSE){
      # 新しいファイル名の確認
      [String]$String1 = "新しいファイル名:" + $NewFileName1 + $StartNo1.tostring("000") + ".jpg でよろしいですか(Y/N)?"
      $myINPUT1 = Read-HostDefault $String1 "N"
    }
    if(($ErrFlg1 -eq $FALSE) -and ($myINPUT1 -eq "Y")){
      # xxxxxxxxx_001.xxx, xxxxxxxxx_002.xxx と昇順で名前を付け替える
      # 一時的な名前($tmpName1)を発生
      $tmpName1 = myRnd1Char(1) # 1文字目は英字
      for($myCNT3=0;$myCNT3 -le 8;$myCNT3++){
        $tmpName1 += myRnd1Char(2) # 2-9文字目は英数字
      }
      $tmpName1 += "_"
      write-host "一時的なファイル名(`$tmpName1)=$tmpName1"
      Read-HostDefault "OK?" > $null # 入力待ち
      # 1回目の変換後にファイル名の重複が発生する場合は中止
      # 検索パタン
      $myPattern = "^" + $tmpName1 + "[0-9]{3}"
      # 重複ファイル数
      $myMatchCount = (Get-ChildItem|Where-Object {$_.Name -match $myPattern}|Measure-Object).Count
      #Write-Host "`$myMatchCount=$myMatchCount"
      if($myMatchCount -ge 1){
        Write-Host "ファイル名の重複が発生するため、ファイル名の変更を中止します。"
        Read-HostDefault "OK?" > $null # 入力待ち
      }else{
        # 拡張子カウンタ
        [int]$myCNT4 = 0
        # 総ファイル数
        [int]$TotalCount1 = 0
        foreach ($tmpExt1 in $myExt1){
          [int]$myCNT2 = 0 # ファイル数のカウンタ
          # 一度目のファイル名一括変換(一時的なファイル名への変換)
          Get-ChildItem -File *.$tmpExt1| Sort-Object Name | ForEach-Object -Begin {$myCNT2 = $StartNo1} -Process { $Newname = $tmpName1+$myCNT2.tostring("000")+$_.extension; rename-item $_ $Newname; $myCNT2++ }
          $StartNo1 = $myCNT2 # 次の拡張子の開始番号
          $myExtCount1 += (Get-ChildItem -File *.$tmpExt1|Measure-Object).Count
          $j=$myExtCount1[$myCNT4]
          $TotalCount1 += $j # 総ファイル数
          Write-Host $tmpExt1"のファイル数="$j
          $myCNT4++
        }
        Write-Host "総ファイル数="$TotalCount1
        Read-HostDefault "OK?" > $null # 入力待ち
        Write-Host "一度目のファイル名一括変換後のファイル名"
        Get-ChildItem # ファイル一覧
        Read-HostDefault "OK?" > $null # 入力待ち
        # if ([String]::IsNullOrEmpty($myINPUT1)){
        # echo "INPUTはNull"
        # }else{
        # echo "INPUTはNullではない"
        # }
        # Read-HostDefault "OK?" > $null
        # ファイル名への変換)
        foreach ($tmpExt1 in $myExt1){
          Get-ChildItem -File *.$tmpExt1 | Rename-Item -NewName { $_.Name -replace $tmpName1,$NewFileName1 }
        }
        # 拡張子カウンタ
        $myCNT4 = 0
        foreach ($tmpExt1 in $myExt1){
          $j=$myExtCount1[$myCNT4]
          if(($tmpExt1 -eq "jpe") -and ($j -ge 1)){
            $myINPUT1 = Read-HostDefault "拡張子(jpe)をjpgに変更しますか(Y/N)?" "N"
            if($myINPUT1 -eq "Y"){
              Write-Host "拡張子のjpeをjpgに置換する。"
              Get-ChildItem -File *.jpe | Rename-Item -NewName { $_ -replace '\.jpe$','.jpg' }
            }
          }
          if(($tmpExt1 -eq "jpeg") -and ($j -ge 1)){
            $myINPUT1 = Read-HostDefault "拡張子(jpeg)をjpgに変更しますか(Y/N)?" "N"
            if($myINPUT1 -eq "Y"){
              Write-Host "拡張子のjpegをjpgに置換する。"
              Get-ChildItem -File *.jpeg | Rename-Item -NewName { $_ -replace '\.jpeg$','.jpg' }
            }
          }
          $myCNT4++
        }
        Write-Host "二度目のファイル名一括変換後のファイル名"
        Get-ChildItem # ファイル一覧
        Read-HostDefault "OK?" > $null # 入力待ち
      }
    }else{
      Write-Host "新しいファイル名の確認でY以外が入力された"
      Write-Host "ファイル名の変更をスキップします。"
      Read-HostDefault "OK?" > $null # 入力待ち
    }
  }else{
    Write-Host "ファイル名を変更しますか(Y/N)? にY以外が入力された"
    Write-Host "ファイル名を変更しません。"
    Read-HostDefault "OK?" > $null # 入力待ち
  }
  $myCNT1++ # 履歴カウンタをインクリメント
  $ErrFlg1 =$FALSE # エラーフラグをリセット
}
End_Process1($CurrentPath1)
ヤバイぜ!(6)  コメント(1) 
共通テーマ:パソコン・インターネット

ヤバイぜ! 6

コメント 1

cheese999

ヤバイぜ! ありがとうございます(^_0)ノ
by cheese999 (2021-06-12 09:41) 

コメントを書く

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

Facebook コメント

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