如何在PowerShell中重命名所有文件类型中的字符串

如何在PowerShell中重命名所有文件类型中的字符串,powershell,Powershell,我有一个包含所有文件类型的文件夹,例如: 10November2017.txt 01October1986.txt 20September2000.dat 13February1992.txt 我正在使用PowerShell运行以下两个任务: 然后搜索扩展名为.txt的所有文件 以“yyyyMMdd.txt”格式重命名所有返回的.txt文件,例如: 10November2017.txt 01October1986.txt 20September2000.dat 13February1992.t

我有一个包含所有文件类型的文件夹,例如:

10November2017.txt
01October1986.txt
20September2000.dat
13February1992.txt
我正在使用PowerShell运行以下两个任务:

  • 然后搜索扩展名为.txt的所有文件
  • 以“yyyyMMdd.txt”格式重命名所有返回的.txt文件,例如:

    10November2017.txt
    01October1986.txt
    20September2000.dat
    13February1992.txt
    
    • 20171110.txt
    • 19861001.txt
    • 19920113.txt
  • 我能够完成任务1,但在任务2上有点困难。 你能帮忙吗

    提前感谢

    使用基于
    BaseName
    属性(不带扩展名的文件名)解析日期,然后将其转换回所需格式的字符串

    使用
    MMMM
    说明符指定月份的全名

    $txtFiles = Get-ChildItem .\path\to\files -Filter *.txt
    foreach($file in $txtFiles){
        try{
            $fileDate = [datetime]::ParseExact($file.BaseName,'ddMMMMyyyy',$null)
            $file |Rename-Item -NewName ('{0:yyyyMMdd}{1}' -f $fileDate,$file.Extension)
        }
        catch {
            Write-Warning "File base name $($file.BaseName) not recognized as valid date"
        }
    }
    
    这是一条单行线:

    gci -File *.txt|where BaseName -match '^(\d{2})(\w{3,9})(\d{4})$'|Ren -NewName {$matches[3]+([DateTime]::ParseExact($matches[2],"MMMM",$CIUS).Month.ToString('00'))+$matches[1]+$_.Extension} -Whatif
    
    如果输出看起来正常,则删除尾随的
    -whatif

    如果您的区域设置与月份名称不匹配,则不能将
    $null
    用于ParseExact,但必须定义不同的区域性变量:

    $CIUS = New-Object system.globalization.cultureinfo("en-US")
    
    并用该变量替换
    $null

    较长的变体

    $CIUS = New-Object system.globalization.cultureinfo("en-US")
    Get-ChildItem -File *.txt|
      Where-Object BaseName -match '^(\d{2})(\w{3,9})(\d{4})$'|
        Rename-Item -NewName {$matches[3]+`
            ([DateTime]::ParseExact($matches[2],"MMMM",$CIUS).Month.ToString('00'))+`
            $matches[1]+`
            $_.Extension"} -Whatif
    
    解释

    • -match RegEx锚定在begin
      ^
      和end
      $
      处,并从day、month name和year构建三个组
    • 重命名中的脚本块按相反顺序接收组aka
      $matches
    • 使用ParseExact将月份名称替换为序号

    如果您曾经需要反转此设置(使用不同的语言环境),例如八月的法语名称:

    PS> $CIFR = New-Object system.globalization.cultureinfo("fr-FR")
    PS> $CIFR.DateTimeFormat.MonthNames[8 -1]
    août
    
    要获取
    cultureinfo
    项目列表:

    [System.Globalization.CultureInfo]::GetCultures([System.Globalization.CultureTypes]::AllCultures)
    

    我建议另一种单行解决方案,可能会短一点:

    Get-ChildItem -Filter "*.txt" -Recurse | Where-Object {$_.BaseName -match "\D"} | Rename-Item -NewName {[datetime]::ParseExact($_.Basename, "ddMMMMyyyy", $null).ToString("yyyyMMdd") + $_.extension}
    
    说明:

    -Filter“*.txt”
    只过滤文本文件

    -Recurse |其中对象{$\ BaseName-match“\D”}
    仅迭代包含非数字字符的对象,以过滤掉新重命名的项

    [datetime]:ParseExact($\u.Basename,“ddMMMMyyyy”,$null)
    将文件名(无扩展名)转换为日期对象


    .ToString(“yyyyymmdd”)+$\扩展名
    将日期对象转换为所需的字符串表示形式并附加扩展名

    您可以显示到目前为止的代码吗?脚本是否会使用以前的文件名生成“yyyyMMdd”?将文件的基本名称解析为日期,然后重新格式化该日期,并相应地重命名该文件。我的意思是,这符合逻辑,但我认为您需要先创建一个数组或向量或任何东西,使用月份名称,然后将.txt文件的前2个字符(priginal)与月份数组中的相同位置-1进行比较,并使用该位置组合一个新字符串,有些原始文件看起来像这样:01Octorber1999.txt,输出文件看起来像01091999.txt(然后将其组装成yyyyMMdd格式),至少我认为OP想要这样。@jeyejow为什么?如果他的示例文件名具有代表性并且与系统区域设置相匹配,那么输入格式显然是
    ddmmyyyy
    -为什么要尝试重新发明轮子?因为您的代码的输出将是,例如,如果输入是01October1999.txt,它将是1999October01.txt,如果您看到OP所需的输出,它必须是,在本例中为19991001.txt,因此必须有一个库(在本例中为相关内容的数组)保存月份名称的文本,以便将其转换为numbers@jeyejow你试过运行代码吗?在
    Rename Item
    中,我使用了格式字符串
    yyyyMMdd
    ——从而为您的example@jeyejow这就是
    ParseExact()
    :-)的全部要点,你得到了一个实际的
    DateTime
    实例太棒了!谢谢你,伙计!谢谢你的帮助