简体   繁体   English

使用 powershell 重命名文件(长且非标准名称)

[英]Renaming files with powershell (long and not standard name)

I'm just getting to know PowerShell.我刚开始了解 PowerShell。

I have a script (got it from an old administrator who quit), it worked well with files, renamed it as needed.我有一个脚本(从一个退出的老管理员那里得到),它可以很好地处理文件,并根据需要重命名。

Old file name for example:旧文件名例如:

mcgruz 16.11.2021 03_30_1720211116_033432.xls 

was renamed to改名为

20211116_mcgruz

or another:或其他:

prim43 15.11.2021 23_00_1920211115_320117.xls  

was renamed to改名为

20211115_prim43

Script:脚本:

# Definition
$srcFld      = "\\domain\MC_REPORT\INCOMING"
$arcFld      = "\\domain\MC_REPORT\ARC"
$UnsortFld   = "\\domain\MC_REPORT\UNSORT"
$destFld     = $UnsortFld
$mcgruzFld   = "\\domain\MC_REPORT\RAIL_RUN_DATE"
$mcdatcFld   = "\\domain\MC_REPORT\DEMURRAGE_AT_THE_CUSTOMS"
$demurrFld   = "\\domain\MC_REPORT\DEMURRAGE"
$prim43Fld   = "\\domain\MC_REPORT\FLAT_CAR_PRICE_GROUP"
$podsylFld   = "\\domain\MC_REPORT\PODSYL"
$pogruzFld   = "\\domain\MC_REPORT\POGRUZKA"
$claimsFld   = "\\domain\MC_REPORT\CLAIMS"
$dislzvFld   = "\\domain\MC_REPORT\DISLZV"
$renummFld   = "\\domain\MC_REPORT\RENUM"
$kontdislFld = "\\domain\MC_REPORT\KONTDISL"

$regex = "(\b\w+\b).(\d+[.]\d+[.]\d+)"

#
$folder = Get-ChildItem $srcFld -Filter *.xls
foreach($file in $folder) {
    $fn=($file.Name -split $regex)
    $fn[2] = date $fn[2] -format yyyyMMdd
    $filenew = $fn[2]+"_"+$fn[1]+".xls"

    switch ($fn[1])
    {
        renumm {
            $destFld = $renummFld 
        }
        mcgruz {
            $destFld = $mcgruzFld
        }
        mcdatc {
            $destFld = $mcdatcFld
        }
        prim43 {
            $destFld = $prim43Fld
        }
        demurr {
            $destFld = $demurrFld
        }
        podsyl {
            $destFld = $podsylFld
        }
        pogruz {
            $destFld = $pogruzFld
        }
        dislzv {
            $destFld = $dislzvFld
        }
        claims {
            $destFld = $claimsFld
        }
        kontdisl {
            $destFld = $kontdislFld
        }
        default {
            $destFld = $UnsortFld
        }
    }

    Copy-Item $file.FullName "$destFld\$filenew" -Recurse
    Copy-Item $file.FullName "$arcFld\$filenew" -Recurse
    Remove-Item $file.FullName -recurse
}

But recently, the vendor changed the files, and now the script does not work correctly.但是最近,供应商更改了文件,现在脚本无法正常工作。

New file name: prim4320211205_230050.xls script renamed it to: _.xls and not safe old file.新文件名: prim4320211205_230050.xls脚本将其重命名为:_. _.xls而不是安全的旧文件。

I must to change the code, but I don't know exactly what to change.我必须更改代码,但我不知道要更改什么。

    $regex = "(\b\w+\b).(\d+[.]\d+[.]\d+)"

#
$folder = Get-ChildItem $srcFld -Filter *.xls

foreach($file in $folder) {
    $fn = ($file.Name -split $regex)
    $fn[2] = date $fn[2] -format yyyyMMdd
    $filenew = $fn[2]+"_"+$fn[1]+".xls"

I will be grateful for your help我会感谢你的帮助

try to use code on local machine.尝试在本地机器上使用代码。 And powershell ISE send error:而 powershell ISE 发送错误:

+ $fn[2] = date $fn[2] -format yyyyMMdd
+               ~~~~~~
    + CategoryInfo          : WriteError: (:) [Get-Date], 
ParameterBindingException
    + FullyQualifiedErrorId : 
ParameterBindingFailed,Microsoft.PowerShell.Commands.GetDateCommand

To handle both file naming formats, you could use below:要处理这两种文件命名格式,您可以使用以下方法:

foreach ($file in (Get-ChildItem -Path $srcFld -Filter '*.xls' -File)) {
    if ($file.BaseName -match '^(.+)(\d{8})_.*') {
        # testing new format like 'prim4320211205_230050'
        $name = $matches[1]
        $filenew = '{0}_{1}{2}' -f $matches[2], $matches[1], $file.Extension
    }
    elseif ($file.BaseName -match '^(\w+) +(\d{1,2}\.\d{1,2}\.\d{4}) .*') {
        # testing old format like 'mcgruz 16.11.2021 03_30_1720211116_033432'
        $name = $matches[1]
        $date = [datetime]::ParseExact($matches[2], 'dd.MM.yyyy', $null)
        $filenew = '{0:yyyyMMdd}_{1}{2}' -f $date, $matches[1], $file.Extension
    }
    else {
        # output a warning thatthe filename could not be parsed out
        Write-Warning "could not rename file '$($file.FullName)'"
        continue   # skip this file and proceed with the next one
    }

    # now proceed with the rest of your code
    $destFld = switch ($name) {
        'renumm' { $renummFld }
        'mcgruz' { $mcgruzFld }
        # etc.
    }
    $file | Copy-Item -Destination (Join-Path -Path $destFld -ChildPath $filenew)
    $file | Copy-Item -Destination (Join-Path -Path $arcFld -ChildPath $filenew)
    $file | Remove-Item -Force
}

Regex expression explained on regex101.com, with test strings: regex101: build, test, and debug regex正则表达式在 regex101.com 上解释,带有测试字符串: regex101:构建、测试和调试正则表达式

(\b\w+\b).(\d+[.]\d+[.]\d+)

1st Capturing Group (\b\w+\b)
\b assert position at a word boundary: (^\w|\w$|\W\w|\w\W)
\w matches any word character (equivalent to [a-zA-Z0-9_])
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
\b assert position at a word boundary: (^\w|\w$|\W\w|\w\W)

. matches any character (except for line terminators)

2nd Capturing Group (\d+[.]\d+[.]\d+)
\d matches a digit (equivalent to [0-9])
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
Match a single character present in the list below [.]
. matches the character . with index 4610 (2E16 or 568) literally (case sensitive)
\d matches a digit (equivalent to [0-9])
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
Match a single character present in the list below [.]
. matches the character . with index 4610 (2E16 or 568) literally (case sensitive)
\d matches a digit (equivalent to [0-9])
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)

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

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