【问题标题】:Powershell match file name and movePowershell 匹配文件名并移动
【发布时间】:2020-08-17 13:30:29
【问题描述】:

我正在尝试使用基于文件名的 powershell 将文件从一个目录移动到另一个目录。

结构为 (letters_ID_L-INT.*)

ID 通常为 7 个字符长,大约有 4 个不同扩展名的文件。

通常为 VH_ID_P-INT。* VH 可以更改,但通常为 2 个字母。示例文件将是。 VH_ID_P-100020WW.txt HR_ID_V-10202334AA.PDF 两个文件的 ID 相同

源目标始终相同,但输出会根据已处理的组数而变化。

一旦发生 10 次匹配,则移至文件夹 2,然后移至文件夹 3 等。

$Source = 'x:\Path\Path'

$Desination = 'x:\Path\desination\destination folder 1'

Foreach ($File in $source) {
$File.Name -match '(*_INT_*.*)';

这里有点卡住了。

【问题讨论】:

  • INT 在您的过滤示例中是什么意思?您的文件名示例不匹配。
  • 忽略第一个并使用提供的示例更清楚
  • 如果这是一个常规的事情,企业范围内的所有文件服务器,为什么要编写这个脚本。使用 MS 在 Windows 服务器上提供的企业工具来执行此操作。这是一个服务调用 FSRM。您不仅可以按名称查找和移动文件,还可以按内容查找和移动文件。它叫FSRM

标签: powershell


【解决方案1】:

使用文件夹 1、2、3.. 等可以通过在你的 foreach 结构中使用两个简单的计数器来实现:

$i = 1
$j = 1

foreach ($File in $source) {
    $j++

    if ($j -eq 10) {
        $i++
        $j = 1
    }

    $Desination = "Path\Folder $i"
}

当处理 10 个项目时,$i 会发生变化

要回答或帮助正则表达式,我需要更多信息。 [a-z]+ 可能有助于用一个或多个重复来表示 a-z 中的任何字符。这包括大写,因为 PowerShell 默认情况下不区分大小写。

【讨论】:

  • 嗨,它通常是 VH_ID_P-INT。* VH 可以更改,但通常是 2 个字母。示例文件将是。 VH_ID_P-100020WW.txt HR_ID_V-10202334AA.PDF 两个文件中的 ID 相同
  • 一个有效的正则表达式可以是"\w{2}_\w{2}_\w-\d+\w{2}\.\w+"。您可以在docs.microsoft.com/en-us/dotnet/standard/base-types/… 处查看语法。 \w{2} 表示两个“字字符”,\d+ 表示 1 个或多个“数字”字符。
【解决方案2】:

这就是我的目标。 抛出错误:该进程无法访问该文件,因为它已被另一个进程使用。

    $Source = 'M:\1'

$i = 1
$j = 1

foreach ($File in $source) {
$File.Name -Match '([A-Z]+_{32}_[A-Z0-9])'
    $j++

    if ($j -eq 10) {
        $i++
        $j = 1
    }
    move-item $File -Destination $Desination
    $Desination = "M:\2 $i"
}

【讨论】:

  • {32} 并不是你认为的意思。由于-match 使用正则表达式,{32} 意味着匹配上一个匹配 32 次。所以它将寻找 32 个下划线。如果你想区分大小写,你应该改用-cmatch
  • 啊,好吧,我正在寻找 32 作为值的长度,我应该使用 0-9 来代替吗?
  • 如果你想匹配 6 位数字,你可以使用[0-9]{6}。如果您需要 6 位或更多位,请使用 [0-9]{6,}。如果需要 0 到 6 位数字,请使用 [0-9]{0,6}
  • 相对于文件移动。当然,在决定要做什么之前,您必须始终检查正在使用的文件(也就是由另一个进程拥有 - 主要是 Office 文档等,而不是文本文件。)。有几种方法可以确定此文件是否被进程锁定。
【解决方案3】:

关于你的...

[这就是我起身的地方。引发错误:该进程无法访问该文件,因为它正被另一个进程使用。]

...您可以重构代码以检查文件锁定并仅处理那些没有锁定的文件,和/或在您这样做之前关闭它们。

注意点:关闭打开的文件,可能/将导致文件损坏/数据丢失。所以,不要只是随意地这样做。

$Source = 'M:\1'

$i = 1
$j = 1

foreach ($File in $source) 
{
$File.Name -Match '([A-Z]+_{32}_[A-Z0-9])'
    $j++

    if ($j -eq 10) 
    {
        $i++
        $j = 1
    }

    Try
    {
        move-item $File -Destination $Desination -ErrorAction Stop
        $Desination = "M:\2 $i"
    }
    Catch {$PSitem.Exception.Message}
}

或者在您的工作中添加类似下面的内容。

Clear-Host
# Remove non-Locked file and show screen output
'D:\temp\abc.txt', 'D:\Documents\Return To Sender.docx','D:\Temp\nonexistent.txt.' | 
ForEach{
    try   
    {
        $TargetFile = (New-Object System.IO.FileInfo $PSitem).Open(
                                            [System.IO.FileMode]::Open, 
                                            [System.IO.FileAccess]::ReadWrite, 
                                            [System.IO.FileShare]::None
                      )
        $TargetFile.Close()  
        Remove-Item -Path $PSItem -WhatIf  
    }
    catch [System.Management.Automation.ItemNotFoundException]{$PSItem.Exception.Message}
    catch {$PSItem.Exception.Message}
}

# Results
<#
What if: Performing the operation "Remove File" on target "D:\temp\abc.txt".
Exception calling "Open" with "3" argument(s): "The process cannot access the file 'D:\Documents\Return To Sender.docx' because it is being used by another process."
Exception calling "Open" with "3" argument(s): "Could not find file 'D:\Temp\nonexistent.txt'."
#>

Clear-Host
# Remove non-Locked file and silence screen output
'D:\temp\abc.txt', 'D:\Documents\Return To Sender.docx','D:\Temp\nonexistent.txt.' | 
ForEach{
    try   
    {
        $TargetFile = (New-Object System.IO.FileInfo $PSitem).Open(
                                            [System.IO.FileMode]::Open, 
                                            [System.IO.FileAccess]::ReadWrite, 
                                            [System.IO.FileShare]::None
                      )
        $TargetFile.Close()  
        Remove-Item -Path $PSItem -WhatIf 
    }
    catch [System.Management.Automation.ItemNotFoundException]{$null = $PSItem.Exception.Message}
    catch {$null = $PSItem.Exception.Message}
}
# Results
<#
What if: Performing the operation "Remove File" on target "D:\temp\abc.txt".
#>

【讨论】:

    猜你喜欢
    • 2014-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多