如果 PowerShell 已存在则复制文件重命名

Copy files renaming if already exists PowerShell

如果文件重复,此脚本可在复制文件时重命名文件。我需要先重命名当前目标文件,然后按原样复制源文件。有什么想法吗?

function Copy-FilesWithVersioning{
    Param(
        [string]$source,
        [string]$destination
    )
    Get-ChildItem -Path $source -File
        ForEach-Object {
            $destinationFile = Join-Path $destination $file.Name
            if ($f = Get-Item $destinationFile -EA 0) {
                # loop for number goes here
                $i = 1
                $newname = $f.Name -replace $f.BaseName, "$($f.BaseName)_$I")
                Rename-Item $destinationFile $newName
            }
            Copy-Item $_ $destination
        }
}

Copy-FilesWithVersioning c:\scripts\Source c:\scripts\DestinationA

错误:

At line:10 char:53
+             if($f = Get-Item $destinationFile -EA 0){
+                                                     ~
Missing closing '}' in statement block or type definition.
At line:8 char:23
+         ForEach-Object{
+                       ~
Missing closing '}' in statement block or type definition.
At line:2 char:34
+ function Copy-FilesWithVersioning{
+                                  ~
Missing closing '}' in statement block or type definition.
At line:13 char:77
+ ...         $newname = $f.Name -replace $f.BaseName, "$($f.BaseName)_$I")
+                                                                         ~
Unexpected token ')' in expression or statement.
At line:15 char:13
+             }
+             ~
Unexpected token '}' in expression or statement.
At line:17 char:9
+         }
+         ~
Unexpected token '}' in expression or statement.
At line:18 char:1
+ }
+ ~
Unexpected token '}' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingEndCurlyBrace

您看到的错误是由这行中虚假的右括号引起的:

$newname = $f.Name -replace $f.BaseName, "$($f.BaseName)_$I")

去掉行尾的括号,这些错误就会消失。

不过,您的代码中还有其他几个错误,因此即使修复了这些错误,代码仍然无法运行。

  • 您在 Get-ChildItemForEach-Object 之间缺少管道。它是将一个 cmdlet 的输出传递给另一个所必需的。

    Get-ChildItem -Path $source -File |
        ForEach-Object {
            ...
        }
    
  • 变量$file未定义。在 PowerShell 管道中,您希望使用 "current object" 变量 ($_)。更改此行

    $destinationFile = Join-Path $destination $file.Name
    

    进入

    $destinationFile = Join-Path $destination $_.Name
    
  • $_ 语句中

    Copy-Item $_ $destination
    

    扩展为文件名,而不是完整路径。将其更改为

    Copy-Item $_.FullName $destination
    

    更好的是,将 Copy-Item 语句 移动到 ForEach-Object 之后,这样您就不需要首先明确指定来源(该 cmdlet 从管道读取输入):

    Get-ChildItem ... | ForEach-Object {
        ...
        $_   # need this line to pass the current object back into the pipeline
    } | Copy-Item -Destination $destination
    

    请注意,您必须将当前对象输出回管道并将目标指定为命名参数 (-Destination $destination),后者才能正常工作。

  • 您检查目标文件夹中是否存在文件有点笨拙。请改用 Test-Path。您可以从当前对象构造新文件名。

    if (Test-Path -LiteralPath $destinationFile) {
        $i = 1
        Rename-Item $destinationFile ($_.BaseName + "_$i" + $_.Extension)
    }
    

试试这个 link 中的代码:https://www.pdq.com/blog/copy-individual-files-and-rename-duplicates/:

$SourceFile = "C:\Temp\File.txt"
$DestinationFile = "C:\Temp\NonexistentDirectory\File.txt"

If (Test-Path $DestinationFile) {
    $i = 0
    While (Test-Path $DestinationFile) {
        $i += 1
        $DestinationFile = "C:\Temp\NonexistentDirectory\File$i.txt"
    }
} Else {
    New-Item -ItemType File -Path $DestinationFile -Force
}

Copy-Item -Path $SourceFile -Destination $DestinationFile -Force