【问题标题】:Powershell Move-Item Rename If File Exists如果文件存在,Powershell 移动项目重命名
【发布时间】:2013-05-26 05:48:42
【问题描述】:

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

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

123.txt 123_1.txt 123_2.txt

【问题讨论】:

  • 我对@9​​87654321@ 知之甚少(这个名字本身就是个笑话……),但它不是提供了一些功能,可以像其他环境一样创建保证唯一的文件名吗?
  • 我找到了一些文档,但没有看到任何关于唯一名称的信息,只是它可以强制移动并覆盖已经存在的文件,或者它会引发错误并跳过移动,留下旧文件和各自目录中的新文件。

标签: powershell rename move


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:
    #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
    }
    

    【讨论】:

      【解决方案3】:

      所以我在这里参加聚会已经很晚了,但是...我有点喜欢这些响应,只是不喜欢在函数中缺少它,所以...我对其进行了修改以实现可重用性。

      我添加了 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来调用它

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-04
        • 2019-02-04
        • 2015-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多