尝试制作一个简单的备份脚本,如下所示:
移动以下
sourceexample1.txt
sourcepathexample2.txt
至
destexample1.txt
destpathexample2.txt
同时,重命名dest
中已存在的任何文件。
我的代码:
$src = "C:UsersUserDesktoptest1"
$dest = "C:UsersUserDesktoptest2"
Get-ChildItem -Path $src -Filter *.txt -Recurse | ForEach-Object {
$num=1
$nextName = Join-Path -Path $dest -ChildPath $_.name
while(Test-Path -Path $nextName)
{
$nextName = Join-Path $dest ($_.BaseName + " ($num)" + $_.Extension)
$num+=1
}
$_ | Move-Item -Destination $nextName
}
这几乎有效,但它将所有文件展平到dest
中的一个文件夹中。(sourcepathexample.txt
变为destexample.txt
(
如何修复?
下面的注释代码片段可以完成任务:
Get-ChildItem -Path $src -Filter *.txt -Recurse |
ForEach-Object {
$num=1
# ChildPath ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
$nextName = Join-Path -Path $dest -ChildPath $_.FullName.Replace("$src", '')
# effective destination for current file
$destNew = $nextName | Split-Path
# create effective destination silently if necessary
if ( -not (Test-Path -Path $destNew) ) {
$null = New-Item $destNew -ItemType Directory
}
while(Test-Path -Path $nextName)
{
# ↓↓↓↓↓↓↓↓
$nextName = Join-Path $destNew ($_.BaseName + " ($num)" + $_.Extension)
$num+=1
}
$_ | Move-Item -Destination $nextName
}
其他方法:
function Get-ItemNameWithNumberIfExist($NewPath, $BaseName, $Extension, $rang)
{
#build a new file name
if ($rang -eq 0)
{
$NewFileName="{0}{1}" -f $NewPath, $BaseName, $Extension
}
else
{
$NewFileName="{0}({1}){2}" -f $NewPath, $BaseName, $rang, $Extension
}
#build a new path file name (use combine for work on every SE)
$NewPathFile=[System.IO.Path]::Combine($NewPath, $NewFileName)
#recursive call if file exist
if (Test-Path -Path $NewPathFile)
{
$rang++
Get-ItemNameWithNumberIfExist $NewPath $BaseName $Extension $rang
}
else
{
$NewPathFile
}
}
$OldPath='C:temptmp1'
$NewPath='C:temptmp2'
Get-ChildItem $OldPath -file -Recurse | %{
$NewPath=$_.DirectoryName.Replace($OldPath, $NewPath)
#create directory without error if exist
New-Item -ItemType Directory -Path $NewPath -Force
#move item and rename if exist
move-item $_.FullName (Get-ItemNameWithNumberIfExist $NewPath $_.BaseName $_.Extension 0)
}