如果文件存在,Powershell Move-Item重命名

时间:2013-05-30 15:11:12

标签: powershell rename move

我有一个powershell脚本,它将所有文件放在一个目录中,重命名第一个并移动它,然后转到下一个文件。有时会有多个文件被重命名为相同的名称(因为它将要进行的系统,不理想并且必须更改)并且覆盖了不应该被-force覆盖的文件。我需要移动所有文件,但也有唯一的名称,所以我们在目标位置提供它们。有没有一种简单的方法让它自动重命名,所以它看起来像:

123.txt 123(1)的.txt 123(2)的.txt

123.txt 123_1.txt 123_2.txt

3 个答案:

答案 0 :(得分:5)

没有内置的方法可以做到这一点。试一试:

$src = "d:\temp"
$dest = "d:\temp1"
$num=1

Get-ChildItem -Path $src -Filter *.txt -Recurse | ForEach-Object {

    $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
}

答案 1 :(得分:0)

#Fixed solution basing on previous answer (variable $num moved into for each loop):

$src = "d:\temp"
$dest = "d:\temp1"

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
}

答案 2 :(得分:0)

所以我在这里参加聚会有点晚了但是......我有点喜欢这些回应只是不喜欢它在函数中的缺失所以......我修改了它以实现可重用性。

我添加了 Name 字段,因为我将其用作另一个过程的一部分,在该过程中我使用正则表达式子字符串过程来获取包含 <owner>-<date_string>-<hash>.<extension> 的文件名并将它们移动为 <file_path>/<owner>/<date_string>.<extension> 格式.

function Move-Item-AutoRename {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline)]
        [String]$Source,
        [Parameter(Mandatory = $true)]
        [String]$Destination,
        [Parameter(Mandatory = $true)]
        [String]$Name
    )
    PROCESS {
        $count = 1
        [System.IO.FileInfo]$nextName = Join-Path -Path $Destination -ChildPath $Name

        while (Test-Path -Path $nextName) {
            $nextName = Join-Path -Path $Destination ($Name.Split(".")[0] + "_$($count)" + $nextName.Extension)
            $count += 1
        }

        Move-Item -Path $Source -Destination $nextName
    }
}

因为我确信其他人可能对这个解决方案的另一部分感兴趣,所以我将它包括在内,只是为了分享。


function Import-UnsortedFiles {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline)]
        [String]$Source,
        [Parameter(Mandatory = $true)]
        [String]$Destination
    )
    PROCESS {
        Get-ChildItem -Path $Source -Include *.xml, *.json | ForEach-Object {
            $results = $_.Name | Select-String -Pattern '^(.*)-([0-9]*_[0-9]*)-.*(\..*)$'
            [System.IO.FileInfo] $dest = (Join-Path -Path $Target -ChildPath "$($results.Matches.Groups[1])/$($results.Matches.Groups[2])$($results.Matches.Groups[3])");
        
            $test = (Test-Path -Path $dest.Directory.FullName -PathType Container)
            if ($test -eq $false) {
                New-Item -Path $dest.Directory.FullName -ItemType Directory;
            }
        
            Move-Item-AutoRename -Source $_.FullName -Destination $dest.Directory.FullName -Name $dest.Name
        }
    }
}

通过调用 Import-UnsortedFiles -Source $Source -Destination $Target

来调用它