问题
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
andForEach-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 statementCopy-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 theForEach-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