过去我使用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>
答案 0 :(得分:0)
正如@AnsgarWiechers指出的那样,您使用的日期格式不正确。
$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上实时查看正则表达式