Powershell 将名称中带有时间戳的文件移动到年/月文件夹中

发布于 2025-01-10 12:15:20 字数 847 浏览 2 评论 0原文

我有很多半小时文件,其名称格式为 A_B_C_YYYYMMDDThhmm_YYYYMMDDThhnn.csv A、B、C 是单词 其中 YYYY 是 4 位数的年份, MM 2 位月份, DD 2 位数的月份日期, hh 一天中的小时,以 2 位数表示, mm 2 位数字表示的分钟, nn 是 mm+30 分钟

如何使用 Powershell 将这些文件移动到基​​于年份和月份的文件夹中?

我根据以前使用过的 script 但它没有为我的文件名格式生成任何输出,可能是因为 match 字符串是错误的:

Push-Location 'path/to/files'
Get-ChildItem _*_*.csv |
  Where-Object {$_.BaseName -match '_(\d{4})(\d{2})T(\d{4})_\d{6}T(\d{4})'} | ForEach-Object {
    $TargetDir = "{0}\{1}" -f $Matches[1],$Matches[2]
    if (!(Test-Path $TargetDir)){MD $TargetDir | Out-Null}
    $_ | Move -Destination $TargetDir 
}

I have a lot of half-hourly files with names in the form A_B_C_YYYYMMDDThhmm_YYYYMMDDThhnn.csv
A, B and C are words
where YYYY is the year in 4 digits,
MM the month in 2 digits,
DD the day of the month in 2 digits,
hh the hour of the day in 2 dgits,
mm the minute in 2 digits,
and nn is mm+30 minutes

How can I move these files into folders based on years and months using Powershell?

I have made an attempt based on a previously used script but it is not producing any output for my filename format, presumably because the match string is wrong:

Push-Location 'path/to/files'
Get-ChildItem _*_*.csv |
  Where-Object {$_.BaseName -match '_(\d{4})(\d{2})T(\d{4})_\d{6}T(\d{4})'} | ForEach-Object {
    $TargetDir = "{0}\{1}" -f $Matches[1],$Matches[2]
    if (!(Test-Path $TargetDir)){MD $TargetDir | Out-Null}
    $_ | Move -Destination $TargetDir 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半世蒼涼 2025-01-17 12:15:21

乍一看,正如您所推测的,您的正则表达式模式与您的文件名不匹配。我已经更改了模式,并使用[datetime]::ParsedExact(..) 提取年份和月份。之前没有测试过,但我相信它应该有效。

不用说,此代码不处理文件冲突,如果存在与要移动到目标的文件之一同名的文件,则会失败。

Push-Location 'path/to/files'

Get-ChildItem -Filter _*_*.csv | ForEach-Object {
    if($_.BaseName -match '(?:\w_){3}(\d{8})T\d{4}_\1T\d{4}') {
        $parsed = [datetime]::ParseExact(
            $Matches[1], 'yyyyMMdd', [cultureinfo]::InvariantCulture
        )
        $folder = '{0:0000}\{1:00}' -f $parsed.Year, $parsed.Month
        $path = Join-Path $PWD.Path -ChildPath $folder
        if(-not (Test-Path $path)) {
            $null = New-Item $path -ItemType Directory
        }
        
        Move-Item -LiteralPath $_.FullName -Destination $path
    }
}

At first glance, your regex pattern, as you presumed, was not matching your file names. I have changed the pattern a bit, and using [datetime]::ParsedExact(..) to extract the year and month. Haven't tested this previously but I believe it should work.

Needles to say, this code is not handling file collision, if there ever is a file with the same name as one of the files being moved to the destination this will fail.

Push-Location 'path/to/files'

Get-ChildItem -Filter _*_*.csv | ForEach-Object {
    if($_.BaseName -match '(?:\w_){3}(\d{8})T\d{4}_\1T\d{4}') {
        $parsed = [datetime]::ParseExact(
            $Matches[1], 'yyyyMMdd', [cultureinfo]::InvariantCulture
        )
        $folder = '{0:0000}\{1:00}' -f $parsed.Year, $parsed.Month
        $path = Join-Path $PWD.Path -ChildPath $folder
        if(-not (Test-Path $path)) {
            $null = New-Item $path -ItemType Directory
        }
        
        Move-Item -LiteralPath $_.FullName -Destination $path
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文