繁体   English   中英

根据文件名中的日期戳移动文件

[英]Move Files Based on Date Stamp in File Name

不幸的是,我是PowerShell的新手,我有一些每月想用PowerShell存档的文件。 每个文件的文件名中都有YYYYMM日期戳。 我想移动日期戳早于24个月的文件。

例:

file1_201903.txt  
file2_201902.txt  
...  
file3_201703.txt (this should be archived)  
file4_201702.txt (this should be archived)

请注意,源文件位于带有多个子文件夹的目录中。 我希望脚本检查所有子文件夹。 无需在目标中复制文件夹。

到目前为止,这是我尝试过的方法:

$SourceDir = 'C:\source'
$DestDir   = 'C:\destination'
$YearsAgo  = 2

$Then = (Get-Date).AddYears(-$YearsAgo).Date

Get-ChildItem -Path $SourceDir |
    Where-Object {
        $DatePart = ($_.BaseName -split '_')[1]

        $FileDate = [DateTime]::ParseExact($DatePart, 'yyyyMMdd', [CultureInfo]::CurrentCulture)

        $FileDate -lt $Then
    } |
    Move-Item -Destination $DestDir

文件名中的日期部分没有Day的值。 因此,格式应为yyyyMM ,而不是yyyyMMdd

由于格式是可排序的字符串,因此您不必转换为DateTime对象,可以继续比较字符串:

$SourceDir = 'C:\source'
$DestDir   = 'C:\destination'
$YearsAgo  = -2
$Then      = '{0:yyyyMM}' -f (Get-Date).AddYears($YearsAgo)  # returns a String "201703"

Get-ChildItem -Path $SourceDir | ForEach-Object {
    $DatePart = ( $_.BaseName -split '_' )[1]
    # comparing sortable date strings
    if ($DatePart -lt $Then) {
        $_ | Move-Item -Destination $DestDir
    } 
}

如果确实要比较DateTime对象,则应这样做:

$SourceDir = 'C:\source'
$DestDir   = 'C:\destination'
$YearsAgo  = -2

$RefDate   = ('{0:yyyyMM}' -f (Get-Date).AddYears($YearsAgo))  # returns a String "201703"
# convert this string into a DateTime object
$Then      = [DateTime]::ParseExact( $RefDate, 'yyyyMM', [cultureinfo]::CurrentCulture )

Get-ChildItem -Path $SourceDir | ForEach-Object {
    $DatePart = ( $_.BaseName -split '_' )[1]
    $FileDate = [DateTime]::ParseExact( $DatePart, 'yyyyMM', [cultureinfo]::CurrentCulture )
    # comparing DateTime objects
    if ($FileDate -lt $Then) {
        $_ | Move-Item -Destination $DestDir
    } 
}

实际上,那看上去还不错。 ;-)但是您的Where-Object -FilterScript块需要一些调整:

$SourceDir = 'C:\source'
$DestDir   = 'C:\destination'
$YearsAgo  = -2
$Then = ( Get-Date ).AddYears( $YearsAgo ).Date

Get-ChildItem -Path $SourceDir -Recurse |
    Where-Object {
        [datetime]::ParseExact( $(( $_.BaseName -split '_' )[1]), 'yyyyMMdd', [cultureinfo]::CurrentCulture ) -lt $Then
    } |
        Move-Item -Destination $DestDir

您可以对Foreach-Object使用更具描述性的方式。 有时候,这样更容易阅读/理解/关注:

Get-ChildItem -Path $SourceDir -Recurse |
    ForEach-Object{
        $DatePart = ( $_.BaseName -split '_' )[1]
        $FileDate = [datetime]::ParseExact( $DatePart, 'yyyyMMdd', [cultureinfo]::CurrentCulture )
        if ($FileDate -lt $Then) {
            Move-Item -Path $_.FullName -Destination $DestDir
        } 
    }

不幸的是,我目前无法测试。 所以请让我知道。 ;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM