Copy files renaming if already exists PowerShell

橙三吉。 提交于 2019-12-25 00:43:12

问题


This script works to rename files while copying them if they are duplicates. I need to rename the current destination file first then copy the source file as is. Any ideas?

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

Errors:

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

回答1:


Try code from this 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 



回答2:


The errors you're seeing are caused by the spurious closing parenthesis in this line:

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

Remove the parenthesis from the end of the line and these errors will disappear.

There are several other mistakes in your code, though, so even with that fixed the code still won't work.

  • You're missing a pipe between the Get-ChildItem and ForEach-Object. It's required for passing the output of one cmdlet to the other.

    Get-ChildItem -Path $source -File |
        ForEach-Object {
            ...
        }
    
  • The variable $file is undefined. In a PowerShell pipeline you want to work with the "current object" variable ($_). Change this line

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

    into

    $destinationFile = Join-Path $destination $_.Name
    
  • $_ in the statement

    Copy-Item $_ $destination
    

    is expanded to just the name of the file, not the full path. Change that into

    Copy-Item $_.FullName $destination
    

    Better yet, move the Copy-Item statement after the ForEach-Object, so you don't need to explicitly specify the source in the first place (the cmdlet reads input from the pipeline):

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

    Note that you must output the current object back to the pipeline and specify the destination as a named parameter (-Destination $destination) for the latter to work.

  • Your check for the presence of a file in the destination folder is a little awkward. Use Test-Path instead. You can construct the new filename from the current object.

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


来源:https://stackoverflow.com/questions/52087244/copy-files-renaming-if-already-exists-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!