PowerShell脚本将带有日期作为名称的文件移动到文件夹

时间:2018-11-16 11:25:23

标签: powershell

过去我使用powershell做过一些基本的脚本,但现在我陷入了困境。

我们有用户将带有特定日期的PDF文件放置在文件名中:

TSE_M001340_04-Nov-2015_bis_03-Nov-2018.pdf

我要完成的工作: 查找“ bis_”之后的日期(在本示例中为“ 03-Nov-2018”),如果它比实际日期早(比现在年轻),则将其移动到另一个文件夹。

到目前为止我尝试过的事情:

$a = dir c:\temp\test
$a | foreach {
    $file = $_.Name;
    $full = $_.FullName

    switch -wildcard ($file) {
        "*bis_*" {
            $file
            [string]$date = ($file.Split("_"))[2]
            $date
            $datetime = [DateTime]::ParseExact($date, "yyyyMMdd", $null)
            $datetime
            if ($datetime -lt (Get-Date)) {
                Move-Item $full "C:\temp\test\copy\"
            }
        }
    } #end switch
} #end foreach 

错误:

  

字符串未被识别为有效的DateTime。

有什么想法吗?

@Florian: 仍然出现错误,所有文件都被复制。 这是变量的输出:

PS C:\Temp\test> $split
bis_

PS C:\Temp\test> $File
TSE_M001340_Dolder AG_04-Nov-2015_bis_03-Nov-2018

PS C:\Temp\test> $date
M001340

PS C:\Temp\test> 
PS C:\Temp\test> 
PS C:\Temp\test> $datetime

PS C:\Temp\test> 
PS C:\Temp\test> $full
C:\temp\test\TSE_M001340_AG_04-Nov-2015_bis_03-Nov-2018.pdf

PS C:\Temp\test>

2 个答案:

答案 0 :(得分:0)

正如@AnsgarWiechers指出的那样,您使用的日期格式不正确。

MWE

$a = dir c:\temp\test
$a | foreach {
    $file = $_.Name;
    $full = $_.FullName

    switch -wildcard ($file) {
        "*bis_*" {
            $file
            [string]$date = ($file.Split("_"))[2]
            $date
            $datetime = [DateTime]::ParseExact($date, "dd-MMM-yyyy", $null)
            $datetime
            if ($datetime -lt (Get-Date)) {
                Move-Item $full "C:\temp\test\copy\"
            }
        }
    } #end switch
} #end foreach 

编辑

似乎所有文件都不遵循相同的结构。我认为您应该根据提供的两个示例在bis_之后使用dat:

  
      
  • TSE_M001340_04-Nov-2015_bis_03-Nov-2018.pdf
  •   
  • file_test_bis_23-APR-2021.pdf
  •   

这是更新的代码:

$a = dir c:\temp\test
$a | foreach {
    $file = $_.BaseName;
    $full = $_.FullName
    $split = "bis_"

    switch -wildcard ($file) {
        "*$split*" {
            $file
            [string]$date = ($file.Split($split))[1]
            $date
            $datetime = [DateTime]::ParseExact($date, "dd-MMM-yyyy", $null)
            $datetime
            if ($datetime -lt (Get-Date)) {
                Move-Item $full "C:\temp\test\copy\"
            }
        }
    } #end switch
} #end foreach

答案 1 :(得分:0)

带有正则表达式的方法,用于在where-Object和
中对日期进行grep 一条管道应该更有效:

# if the abbreviated month names compply with the current culture
$CI = Get-Culture

# or a selected deviating culture
#$CI = New-Object system.globalization.cultureinfo("de-DE")

$RE = "_bis_(\d{2}-("+($CI.DateTimeFormat.AbbreviatedMonthNames -ne '' -join '|')+")-20\d{2})"

Get-ChildItem | Where-Object {$_.Name -match $RE -and 
    ([datetime]::ParseExact($Matches[1],"dd-MMM-yyyy",$CI) -lt [datetime]::now)}|
        Move-Item -Destination "C:\temp\test\copy\" -WhatIf

如果输出看起来正常,请删除-WhatIf

为了更好地解释文化信息返回的$CI

在我的德语语言环境中

> $CI = Get-Culture
> $CI.DateTimeFormat.AbbreviatedMonthNames -ne '' -join '|'
Jan|Feb|Mrz|Apr|Mai|Jun|Jul|Aug|Sep|Okt|Nov|Dez

> $CI = New-Object system.globalization.cultureinfo("en-US")
> $CI.DateTimeFormat.AbbreviatedMonthNames -ne '' -join '|'
Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec
> $RE = "_bis_(\d{2}-("+($CI.DateTimeFormat.AbbreviatedMonthNames -ne '' -join '|')+")-20\d{2})"
> $RE
_bis_(\d{2}-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-20\d{2})

regex101.com上实时查看正则表达式