從 CSV 重命名檔案
我正在嘗試撰寫一個腳本來使用 csv 作為索引檔案來重新組織檔案夾結構中的檔案,但我無法弄清楚如何解決 Rename-Item 錯誤。
問題
- 是否有其他方法可以撰寫此腳本以便更輕松地獲得相同的結果?
- 如何將正確的引數傳遞給 Rename-Item?
我的 csv 檔案模板
folderName newName oldName
---------- ------- -------
01 Course Overview 01_Course_Overview 1280x720.mp4
02 Introduction to PowerShell 01_Introduction to PowerShell 1280x720 (1).mp4
02 Introduction to PowerShell 02_Who Is This Course For? 1280x720 (2).mp4
02 Introduction to PowerShell 03_What Is PowerShell? 1280x720 (3).mp4
02 Introduction to PowerShell 04_Windows PowerShell and PowerShell 7 1280x720 (4).mp4
PowerShell 腳本
$csv = Import-Csv '.\index.csv' -Delimiter ';'
$newFolders = $csv.folderName | Sort-Object -Unique
$listFolders = Get-ChildItem -Directory | Select-Object Name
$listFiles = Get-ChildItem | Where {$_.extension -eq ".mp4"}
ForEach ($a in $newFolders){
If ($listFolders.Name -contains $a){
Write-Host "The Folder $a exist"
}
else{
New-Item -Path $pwd.Path -Name $a -Type Directory | Out-Null
Write-Host "The folder $a has been created"
}
}
ForEach ($b in $csv){
If ($listFiles.Name -contains $b.oldName){
Write-Host "File $($b.oldName) exist"
Write-Host "Renaming file to: "$($b.newName)"
#Rename-Item $($b.oldName) -NewName $($b.newName)
#Write-Host "Moving file to: "$($b.folderName)"
#Move-Item .\$($b.newName) -Destination .\$($b.folderName)
}
else{
Write-Host "File $($b.oldName) doesn't exist" `n
}
}
執行重命名專案時出錯
No D:\Downloads\Pluralsight\_PowerShell_Essentials\01_Powershell_Getting_Started\Temp\indexfiles.ps1:30 caractere:9
Rename-Item $($b.oldName) -NewName $($b.newName)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidArgument: (D:\Downloads\Pl...280x720 (2).mp4:String) [Rename-Item], ArgumentException
FullyQualifiedErrorId : RenameItemArgumentError,Microsoft.PowerShell.Commands.RenameItemCommand
uj5u.com熱心網友回復:
在這里,您有一個如何做到這一點的示例,這主要是一個測驗用例,它將創建您在 CSV 上向我們展示的檔案,并根據folderName列將它們移動到新檔案夾中。
該代碼將在當前目錄中查找檔案,然后使用該檔案夾中的真實檔案Set-Location( cd) 對其進行測驗。
如果您不確定代碼是否可以作業,您可以添加一個-WhatIf開關到Rename-Itemand Move-Item。
請注意,我已從?該newName列中洗掉,因為它在 Windows 上是無效字符。有關更多詳細資訊,請參閱此答案。
# Go to a temporary folder for testing
Set-Location path/to/temporaryfolder/here
# Here you would use:
# $csv = Import-Csv path/to/csv.csv
$csv = @'
folderName newName oldName
01 Course Overview 01_Course_Overview 1280x720.mp4
02 Introduction to PowerShell 01_Introduction to PowerShell 1280x720 (1).mp4
02 Introduction to PowerShell 02_Who Is This Course For 1280x720 (2).mp4
02 Introduction to PowerShell 03_What Is PowerShell 1280x720 (3).mp4
02 Introduction to PowerShell 04_Windows PowerShell and PowerShell 7 1280x720 (4).mp4
'@ -replace ' ',',' | ConvertFrom-Csv
# Create test files, this part is only for testing the code
$csv.foreach({ New-Item $_.oldName -ItemType File })
foreach($line in $csv)
{
if(-not (Test-Path $line.folderName))
{
# Create the Folder if it does not exist
New-Item $line.folderName -ItemType Directory -Verbose
}
Rename-Item -LiteralPath $line.oldName -NewName $line.newName
Move-Item -LiteralPath $line.newName -Destination $line.folderName
}
uj5u.com熱心網友回復:
如果我理解正確,您的真實 CSV 檔案包含檔案夾和/或檔案名,其中包含無效字符,例如?.
要解決此問題,您可以選擇先從 CSV 檔案中洗掉這些字符,或者確保在創建檔案夾或重命名檔案之前洗掉它們。
對于這兩個選項,您都可以使用這個小輔助函式:
function Remove-InvalidNameChars {
param(
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[String]$Name,
[ValidateSet('File', 'Path')]
[string]$Type ='File'
)
if ($Type -eq 'File') {
$invalidChars = [IO.Path]::GetInvalidFileNameChars() -join ''
}
else {
$invalidChars = [IO.Path]::GetInvalidPathChars() -join ''
}
# build a regex string from the invalid characters
$removeThese = "[{0}]" -f [RegEx]::Escape($invalidChars)
# output the name with invalid characters removed
$Name -replace $removeThese
}
方法 1:從 CSV 檔案中洗掉無效字符并使用清理后的資料:
$sourcePath = 'D:\Test'
$csvFile = Join-Path -Path $sourcePath -ChildPath 'index.csv'
$csvData = Import-Csv -Path $csvFile -Delimiter ';'
foreach ($item in $csvData) {
$item.folderName = Remove-InvalidNameChars -Name $item.folderName -Type Path
$item.newName = Remove-InvalidNameChars -Name $item.newName -Type File
}
$csvData | Export-Csv -Path $csvFile -Delimiter ';' -Force # rewrite the CSV file if you like
# now use the cleaned-up data in $csvData for the rest of the code:
foreach ($item in $csvData) {
# create the output folder if this does not already exist
$targetPath = Join-Path -Path $sourcePath -ChildPath $item.folderName
$null = New-Item -Path $targetPath -ItemType Directory -Force
# move and rename the file if found
$sourceFile = Join-Path -Path $sourcePath -ChildPath $item.oldName
if (Test-Path -Path $sourceFile -PathType Leaf) {
$targetFile = Join-Path -Path $targetPath -ChildPath $item.newName
Move-Item -Path $sourceFile -Destination $targetFile
}
}
方法 2:保留 csv 資料原樣,并確保在重命名/移動時洗掉無效字符:
$sourcePath = 'D:\Test'
$csvFile = Join-Path -Path $sourcePath -ChildPath 'index.csv'
$csvData = Import-Csv -Path $csvFile -Delimiter ';'
foreach ($item in $csvData) {
# create the output folder if this does not already exist
$targetPath = Join-Path -Path $sourcePath -ChildPath (Remove-InvalidNameChars -Name $item.folderName -Type Path)
$null = New-Item -Path $targetPath -ItemType Directory -Force
# move and rename the file if found
$sourceFile = Join-Path -Path $sourcePath -ChildPath (Remove-InvalidNameChars -Name $item.oldName -Type File)
if (Test-Path -Path $sourceFile -PathType Leaf) {
$targetFile = Join-Path -Path $targetPath -ChildPath (Remove-InvalidNameChars -Name $item.newName -Type File)
Move-Item -Path $sourceFile -Destination $targetFile
}
}
請注意,Move-Item可以將檔案移動到新目的地并同時重命名,因此您不需要Rename-Item
PS 我注意到在您的示例 CSV 中,檔案名沒有擴展newName名。
如果在現實生活中是這種情況,您還需要添加這些。
為此,將Move-Item行更改為:
Move-Item -Path $sourceFile -Destination ([IO.Path]::ChangeExtension($targetFile, [IO.Path]::GetExtension($sourceFile)))
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/416705.html
標籤:
