手動ではあまりやりたくない大量のフォルダ・ファイル操作。記事タイトルの作業を行う必要に迫られたので、スクリプトを作成した。再利用できるようここに記載しておく。
仕様
- 指定したフォルダに含まれる全てのサブフォルダに対して、そのサブフォルダに含まれるファイル・フォルダを上の階層に移動する。
- 移動後、元のサブフォルダは削除する。
- 名前の重複を避けるため、移動するファイル・フォルダには元のサブフォルダを名前の先頭に付ける。
つまり、これを、
TargetFolder/
├── SubFolder1/
│ ├── SubFolder4/
│ │ └── Text2.txt
│ └── Text3.txt
├── SubFolder2/
│ └── Text4.txt
├── SubFolder3
└── Text1.txt
こうする。
TargetFolder/
├── SubFolder1_SubFolder4/
│ └── Text2.txt
├── SubFolder1_Text3.txt
├── SubFolder2_Text4.txt
└── Text1.txt
コード
MoveToParentLayer.ps1
# パラメータ設定
$targetFolder = "C:\Path\TargetFolder" # 操作対象のフォルダ
$delimiter = "_" # サブフォルダ名と元のファイル・フォルダ名の間の区切り文字
# 確認ダイアログ
$response = Read-Host "この操作は元に戻せません。続行しますか? (Y/N)"
if ($response -ne "Y") {
Write-Host "操作がキャンセルされました。"
exit
}
# 指定フォルダ直下の全てのフォルダを取得
Get-ChildItem -Path $targetFolder -Directory | ForEach-Object {
$currentFolder = $_.FullName # 現在のフォルダパス
$folderName = $_.Name # 現在のフォルダ名
# 現在のフォルダ内の全てのファイルを一つ上の階層に移動
Get-ChildItem -Path $currentFolder -File | ForEach-Object {
$sourceFilePath = $_.FullName # 元のファイルパス
$newFileName = "${folderName}${delimiter}$($_.Name)" # 新しいファイル名
$destinationPath = Join-Path -Path $targetFolder -ChildPath $newFileName
Move-Item -Path $sourceFilePath -Destination $destinationPath
Write-Host "Moved File: $sourceFilePath to $destinationPath"
}
# 現在のフォルダ内の全てのサブフォルダを一つ上の階層に移動
Get-ChildItem -Path $currentFolder -Directory | ForEach-Object {
$sourceFolderPath = $_.FullName # 元のサブフォルダパス
$newFolderName = "${folderName}${delimiter}$($_.Name)" # 新しいフォルダ名
$destinationPath = Join-Path -Path $targetFolder -ChildPath $newFolderName
Move-Item -Path $sourceFolderPath -Destination $destinationPath
Write-Host "Moved Folder: $sourceFolderPath to $destinationPath"
}
# 元のフォルダを削除
Remove-Item -Path $currentFolder -Recurse -Force
Write-Host "Removed Folder: $currentFolder"
}
Write-Host "処理が完了しました。"
確認ダイアログも出すようにしているが、一度実行してしまうと元に戻すのは難しいので注意してほしい。