【问题标题】:Powershell: Copy and modify filenamePowershell:复制和修改文件名
【发布时间】:2019-12-17 21:42:32
【问题描述】:

我需要以分钟为单位将文件从网络驱动器复制到本地驱动器。复制完成后,我需要按照以下要求修改文件名:

示例文件名:

Ser1-PRD-CL4$Entreprise_AG2_MyCompany-NA_DB_Name_02_LOG_20191217_094501.trn

  1. 从网络目录复制 35 分钟前创建的所有文件,例如\Server\本地目录的路径 D:\NameofDB (我能够实现复制部分,但想知道是否应该放置任何标志以防止再次复制相同的文件,复制的文件将修改其名称,因此不确定我们如何跟踪)
  2. 一旦复制,修改所有复制文件的名称如下:

    一个。删除单词“MyCompany”之前出现的所有字符

    b.删除下划线和单词 LOG "_LOG"

    c。删除日期和交易编号之间的下划线 (_):20191217_094501

我已经实现了从文件名中复制和删除“_LOG”,但在剩余要求方面遇到了问题。

任何意见将不胜感激:

重要提示:目标目录中将有其他文件被移动名称并在目标目录中修改其名称,不应修改这些文件名。

$Sourcefolder= "D:\Temp"
$Targetfolder= "D:\Temp2"
Get-ChildItem -Path $Sourcefolder -Recurse|
Where-Object {
  $_.LastWriteTime -gt [datetime]::Now.AddMinutes(-60)
}| Copy-Item -Destination $Targetfolder
Get-ChildItem -Path $Targetfolder | Rename-Item -NewName {$_.Name -replace "_LOG", ""} 
Get-ChildItem -Path $Targetfolder | Rename-Item -NewName {$_.Name -replace '^MyCompany'} #This is not working

【问题讨论】:

    标签: powershell filenames


    【解决方案1】:

    关于重复复制相同文件的第一个问题,请参阅:Powershell script that can log already scanned files and ignore them on next run?

    对于 2a)

    Get-ChildItem -Path $Targetfolder | Rename-Item -NewName {$_.Name.substring($_.Name.indexof("MyCompany"))}
    

    请注意字符串区分大小写。

    【讨论】:

    • 谢谢,虽然它可以工作,但代码会创建大量重复文件。我猜重命名保留了我猜的原始文件名?在这种情况下,拆分或修剪功能会做得更好吗?
    • @Ali rename-item 不保留旧文件。
    【解决方案2】:

    你可以试试这个:

    get-childitem-path "\\server\share\path" -recurse | foreach {
      if ($_.LastWriteTime -gt [DateTime]::NowAddMinutes(-60)) {
        $TheName = $_.Name -replace "_LOG", ""
        $TheName = $TheName -replace "\d_\d", "$1$2"
        $TheName = $TheName -replace ".*MyCompany", "MyCompany"
        Copy-Item -path $_ -destination {join-path "TargetPath" $TheName}
      }
    }
    

    【讨论】:

      【解决方案3】:

      您可以在复制时使用 Copy-Item 指定一个新名称(因此之后无需重命名)。看看下面的代码就明白了:

      $Sourcefolder= "D:\Temp"
      $Targetfolder= "D:\Temp2"
      Get-ChildItem -Path $Sourcefolder -Recurse |
          Where-Object {
              $_.LastWriteTime -gt [datetime]::Now.AddMinutes(-60)
          } | ForEach-Object {
              $newname = $_.Name.Replace('_LOG','')                       # removes _LOG  
              $newname = $newname -Replace "(\d)_(\d)","$1$2"             # replace underscore between the digits
              $newname = $newname -Replace "(.*)Mycompany","MyCompany$1"  # gets rid of anything before the word "MyCompany"
              Copy-Item -Path $_ -Destination (Join-Path $Targetfolder $newname)
          }
      

      【讨论】:

      • 这听起来很有希望,您能否在字符串“MyCompany”之前添加第三个删除所有内容的要求。
      • 我更新了答案。请注意,必须有更好的方法来做到这一点,但我不是正则表达式专家。我写的东西可以解决问题。
      • 谢谢,但是我收到以下错误: Copy-Item : Cannot find path 'D:\Temp2\Ser1-PRD-CL4$Entreprise_AG2_MyCompany-NA_DB_Name_LOG_20191218_074502.trn' 因为它不存在.在 line:10 char:9 + Copy-Item -Path $_ -Destination (Join-Path $Targetfolder $newname) + ~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (D :\Temp2\Ser1-P...1218_074502.trn:String) [ Copy-Item], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
      • 是的,它确实存在。
      【解决方案4】:

      我在这里尝试使用正则表达式前瞻和后瞻https://www.regular-expressions.info/lookaround.html,所以-replace 只会去掉实际匹配的部分。

      dir | 
      copy-item -destination { 
        $_.name -replace '.*(?=MyCompany)' -replace '_LOG' -replace '(?<=\d)_(?=\d)' } -whatif
      
      What if: Performing the operation "Copy File" on target 
      Item:        /Users/js/foo/MyServer$Entreprise_AG2_MyCompany-NA_DB_Name_LOG_20191217_094501.trn 
      Destination:                         /Users/js/foo/MyCompany-NA_DB_Name_20191217094501.trn".
      

      【讨论】:

        猜你喜欢
        • 2017-12-30
        • 1970-01-01
        • 2018-04-21
        • 2023-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-21
        • 1970-01-01
        相关资源
        最近更新 更多