コンテンツへスキップ

【PowerShell】ファイル名を一括処理で連番の名前に変更する。

コマンドプロンプトだと、バッチファイルにしないといけないから、
PowerShell ならささっとファンクションを書いて実行できるのではと。

ファイル名を一括処理で連番の名前に変更する。

リネーム用スクリプト

PowerShell にコピぺすると、test、test2 ファンクションが使えるようになります。

カレントフォルダ内のファイルのみを全部「img_連番.拡張子」にします。
ファイルの種類は気にしてないので、ファイルの種類ごとにリネームしたい場合は、
Get-ChildItem のフィルタを変更、またはIF 文を挿入して拡張子を判別するようにしてください。
あと、実行場所にはくれぐれも気を付けてね^^

function test {
	$number = 1
	Get-ChildItem -File | ForEach-Object {
		$NameString = "img_" + $number.ToString("0000")+ $_.Extension
		$number++
		Rename-Item $_.Name -NewName $NameString
	}	
}

JPG ファイルだけリネームする場合。

function test {
	$number = 1
	Get-ChildItem ./*.jpg | ForEach-Object {
		$NameString = "img_" + $number.ToString("0000")+ $_.Extension
		$number++
		Rename-Item $_.Name -NewName $NameString
	}	
}

ファイル名はそのままで、拡張子の前に番号を挿入します。
拡張子なしのファイルは無視します。

function test2 {
	$number = 1
	Get-ChildItem -File | ForEach-Object {
		$dot = $_.Name.IndexOf(".")
		if( $dot -gt -1 ){
			$NameString = $_.Name.Insert( $dot, "_" + $number.ToString("0000"))
			$number++
			Rename-Item $_.Name -NewName $NameString
		}
	}
}

PowerShell の呼び出し。

エクスプローラーから呼び出すと、そのフォルダがカレントディレクトリになるので便利です。
また、以前は「コマンドプロンプトを開く」だったけど、現在はPowerShell っす。

フォルダを選択した状態で行うと、そのフォルダがターゲットになります。
必ず、プロンプトで確認してください。

フォルダをシフトキー押しながら右クリックでもこのメニューが出せます。

図1: エクスプローラーでフォルダを選択し右クリックした状態のメニュー。「Windows PowerShell を開く(R)」のサブメニューが表示されている
図1: エクスプローラーでフォルダを選択し右クリックした状態のメニュー。「Windows PowerShell を開く(R)」のサブメニューが表示されている

以下、作るにあたっての四苦八苦

function func{ }で処理を書いておけば、一括処理として呼び出せることは知っているので、
具体的にどうやって書けばいいかを考えていきます。

> function test {
>>  Get-ChildItem -Path ./
>> }
図2: PowerShellでfunction testを定義しGet-ChildItemでファイル一覧を取得するコードを実行した結果。ファイルのモード・更新日時・サイズ・名前が一覧表示されている
図2: PowerShellでfunction testを定義しGet-ChildItemでファイル一覧を取得するコードを実行した結果。ファイルのモード・更新日時・サイズ・名前が一覧表示されている

結構いきなり正解っぽいのをもってきてくれました。

図4: Bing Copilotに「powershellでファイル名を一括で変更する」と質問し、Rename-ItemとGet-ChildItem、-replace演算子を使ったサンプルコードが回答されている
図4: Bing Copilotに「powershellでファイル名を一括で変更する」と質問し、Rename-ItemとGet-ChildItem、-replace演算子を使ったサンプルコードが回答されている

ただ、サンプルコードを貼るだけでは応用が利かないし、
どちらにしろ、うまく動かんかったし。

あと、スクリプトっぽく書きたい。

図5: Bing Copilotに「Get-ChildItem の使いかた」と質問し、Get-ChildItemの基本構文と-Nameパラメーターなどの説明が回答されている
図5: Bing Copilotに「Get-ChildItem の使いかた」と質問し、Get-ChildItemの基本構文と-Nameパラメーターなどの説明が回答されている

単に「Get-ChildItem」をスクリプトに組み込んで連続処理しようとしても、
Get-ChildItem の処理は単独でファイル一覧を取得してしまう。

そこでパイプを使うと、ファイルを一つ取り込むごとにパイプ先の処理を実行するようになって、
結果的にファイルの数だけループ処理する感じになる。

しかし下記のテストコードはエラーに。(※$_ は渡されたオブジェクト)

Get-ChildItem | echo $_

そこで、Get-ChildItem をパイプで使うときのことを聞いてみる。

図6: Bing Copilotに「Get-ChildItem パイプ」と質問し、パイプ(|)でWhere-ObjectやSort-Objectと組み合わせる使い方が回答されている
図6: Bing Copilotに「Get-ChildItem パイプ」と質問し、パイプ(|)でWhere-ObjectやSort-Objectと組み合わせる使い方が回答されている

なるほど、いったん「ForEach-Object 」に渡せばいいのか。

function test{
>> Get-ChildItem | ForEach-Object {
>> echo "------------" $_.name "------------" }
>> }

そのほかのパーツについても確認。

変数の使い方。

図7: Bing Copilotに「powershell 変数の定義のしかた」と質問し、$記号を使った変数の定義方法($a = 10など)が回答されている
図7: Bing Copilotに「powershell 変数の定義のしかた」と質問し、$記号を使った変数の定義方法($a = 10など)が回答されている

文字列の結合も。

図8: Bing Copilotに「PowerShell 文字列連結」と質問し、+演算子や-join演算子など複数の連結方法が回答されている
図8: Bing Copilotに「PowerShell 文字列連結」と質問し、+演算子や-join演算子など複数の連結方法が回答されている

なるほど。じゃあ、こんな感じで。

function test {
	$number = 1
	Get-ChildItem | ForEach-Object {
		$NameString = "img_" + $number.ToString("0000")+ $_.Extension
		$number++
		Rename-Item $_.Name -NewName $NameString
	}	
}
図9: PowerShellで、Get-ChildItemをForEach-Objectにパイプし、連番文字列とファイルの拡張子を組み合わせてRename-Itemでリネームするfunction testを定義・実行している
図9: PowerShellで、Get-ChildItemをForEach-Objectにパイプし、連番文字列とファイルの拡張子を組み合わせてRename-Itemでリネームするfunction testを定義・実行している

図10: エクスプローラーの表示。img_0001.jpgからimg_0012.jpgまで連番にリネームされたファイル一覧
図10: エクスプローラーの表示。img_0001.jpgからimg_0012.jpgまで連番にリネームされたファイル一覧

でも、このコードだとフォルダも一緒に連番にリネームするから、、、
フォルダを取得しないように修正。

図11: エクスプローラーの表示。フォルダ(img_0001〜img_0004)もファイルと一緒に連番の名前にリネームされてしまっている
図11: エクスプローラーの表示。フォルダ(img_0001〜img_0004)もファイルと一緒に連番の名前にリネームされてしまっている
function test {
	$number = 1
	Get-ChildItem -File | ForEach-Object {
		$NameString = "img_" + $number.ToString("0000")+ $_.Extension
		$number++
		Rename-Item $_.Name -NewName $NameString
	}	
}
図12: エクスプローラーの表示。Image、logs、Output、Regularisationなどのフォルダとimg_0003.JPG〜img_0008.JPGのファイルが並んでいる
図12: エクスプローラーの表示。Image、logs、Output、Regularisationなどのフォルダとimg_0003.JPG〜img_0008.JPGのファイルが並んでいる

ついでに拡張子の前にナンバリングを挿入するバージョンも

ファイル名の後ろにナンバリングだけ追加する感じのやつも作っておこう。

文字列操作はどんなのがありますか?

図13: Bing Copilotに「PowerShell 文字列操作」と質問し、文字列の作成・結合・分割・変換・検索・削除・挿入・置換などの操作方法が回答されている
図13: Bing Copilotに「PowerShell 文字列操作」と質問し、文字列の作成・結合・分割・変換・検索・削除・挿入・置換などの操作方法が回答されている

検索と、挿入があればいいよね。

図14: Bing Copilotに「indexOf について詳しく」と質問し、[string]クラスのIndexOfメソッドで文字列の位置を検索する使い方が回答されている
図14: Bing Copilotに「indexOf について詳しく」と質問し、[string]クラスのIndexOfメソッドで文字列の位置を検索する使い方が回答されている

挿入ってどんな感じ?

図15: Bing Copilotに「文字列の挿入について詳しく」と質問し、[string]クラスのInsertメソッドで文字列を挿入する使い方が回答されている(例:$str.Insert(2,"Power"))
図15: Bing Copilotに「文字列の挿入について詳しく」と質問し、[string]クラスのInsertメソッドで文字列を挿入する使い方が回答されている(例:$str.Insert(2,”Power”))

拡張子がなかった場合に何がおきるかわからないから、
拡張子のある・なしの判定もいれないとね。

図16: Bing Copilotに「PowerShell 条件分岐」と質問し、if・elseif・else文の基本構文が回答されている
図16: Bing Copilotに「PowerShell 条件分岐」と質問し、if・elseif・else文の基本構文が回答されている

演算子でハマる。

図17: Bing Copilotに「ps 比較演算子」と質問し、-eq・-ne・-ceqなどの等式演算子の一覧が回答されている
図17: Bing Copilotに「ps 比較演算子」と質問し、-eq・-ne・-ceqなどの等式演算子の一覧が回答されている
function test2 {
	$number = 1
	Get-ChildItem -File | ForEach-Object {
		$dot = $_.Name.IndexOf(".")
		if( $dot -gt -1 ){
			$NameString = $_.Name.Insert( $dot, "_" + $number.ToString("0000"))
			$number++
			Rename-Item $_.Name -NewName $NameString
		}
	}
}

これだけ作っておけば、応用しやすいよね。

以上です。

(Visited 980 times, 1 visits today)

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です