簡體   English   中英

如何復制文件列表並在PowerShell循環中重命名它們

[英]How do I copy a list of files and rename them in a PowerShell Loop

我們正在將一長串文件從它們的不同目錄復制到一個位置(同一服務器)。 到達那里后,我需要重命名它們。

我能夠移動文件,直到發現要移動(和重命名)的文件名列表中存在重復項。 它不允許我將文件多次復制到同一目標位置。

以下是移動后的文件名列表:

"10.csv",
"11.csv",
"12.csv",
"13.csv",
"14.csv",
"15.csv",
"16.csv",
"17.csv",
"18.csv",
"19.csv",
"20.csv",
"Invoices_Export(16) - Copy.csv" (this one's name should be "Zebra.csv")

我寫了幾個foreach循環,但是不能正常工作。

該腳本可以很好地移動文件。 是重命名無法按我想要的方式工作。 第一個文件未重命名; 其他文件重命名。 但是,它們也將移動的文件保留在原位。

此腳本需要具有3列的csv:

  1. 文件的路徑,包括文件名(例如c:\\temp\\smefile.txt
  2. 文件的目的地,包括文件名(例如c:\\temp\\smefile.txt
  3. 文件的新名稱。 只是名稱和范圍。
# Variables
$Path = (import-csv C:\temp\Test-CSV.csv).Path
$Dest = (import-csv C:\temp\Test-CSV.csv).Destination
$NN = (import-csv C:\temp\Test-CSV.csv).NewName

#Script
foreach ($D in $Dest) {
    $i -eq 0
    Foreach ($P in $Path) {
        Copy-Item $P -destination C:\Temp\TestDestination -force
    }

    rename-item -path "$D" -newname $NN[$i] -force
    $i += 1
}

本身沒有錯誤,只是沒有我期望的結果。

歡迎使用Stack Overflow!

有幾種方法可以解決重復名稱的情況:

  1. 使用Test-Path檢查文件是否已在目標中。 如果是這樣,請啟動一個while循環,在該名稱的末尾附加一個數字,然后檢查該數字是否存在。 使用Test-Path每次檢查后增加您追加的數字。 不斷循環,直到Test-Path回來$false ,然后break了循環。
  2. 編寫錯誤消息,然后跳過CSV中的該行。

我將使用上述方法2顯示腳本的重構版本:

$csv = Import-Csv 'C:\temp\Test-CSV.csv'

foreach ($row in $csv)
{
    $fullDestinationPath = Join-Path -Path $row.Destination -ChildPath $row.NewName

    if (Test-Path $fullDestinationPath)
    {
        Write-Error ("The path '$fullDestinationPath' already exists. " + 
                     "Skipping row for $($row.Path).")

        continue
    }

    # You may also want to check if $row.Path exists before attempting to copy it

    Copy-Item -Path $row.Path -Destination $fullDestinationPath
}

現在您的問題已得到回答,下面是一些改進代碼的想法:

  1. 盡可能避免在標識符(變量名,函數名等)中使用首字母縮寫詞和縮寫。 請記住,代碼是為人類編寫的,其他人必須能夠理解您的代碼。 使一切變得盡可能明顯。 最終,即使是Future-You™,其他人也必須閱讀您的代碼!
  2. 不要重復自己(稱為“干”原理)。 正如Lee_daily在評論中提到的那樣,您不需要導入CSV文件三次。 將其一次導入到變量中,然后使用該變量訪問屬性。
  3. 嘗試保持一致。 PowerShell不區分大小寫,但是您應該選擇一種樣式並堅持使用(即ForEachforeachRename-Itemrename-item等)。 我建議使用PascalCase,因為PowerShell cmdlet都在PascalCase中。
  4. 將文字路徑用單引號引起來(如果需要字符串插值,則用雙引號引起來)。 路徑中可以有空格且不帶引號,PowerShell會在您傳遞另一個參數時解釋空格。
  5. $i -eq 0不是賦值語句,它是一個布爾表達式。 當您運行$i -eq 0 ,PowerShell將返回$true$false因為您詢問的是$i存儲的值是否為0 要將值0分配給$i ,您需要這樣編寫: $i = 0
  6. $i += 1沒什么問題,但是如果您願意,可以將其縮短為$i++
  7. 如果可以,請嘗試檢查代碼可能附帶的常見問題。 始終考慮可能出問題的地方。 如果我復制文件,可能會出什么問題?源文件或文件夾是否存在?從CSV提取的名稱是有效的路徑名還是包含路徑中無效的字符(如: ?” 這就是所謂的防御性編程,它將為您節省許多麻煩。 與生活中的任何事情一樣,請注意不要過分。 僅檢查可能的情況; 罕見的邊緣情況只會引起錯誤。
  8. 編寫一些不錯的日志,以便您可以查看運行時發生的情況。 PowerShell提供了一對稱為Start-TranscriptStop-Transcript的出色cmdlet。 這些cmdlet記錄發送到PowerShell控制台窗口的所有輸出,以及一些系統信息,例如計算機上安裝的PowerShell版本。 非常便利!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM