Home > Enterprise >  Renaming files with powershell (long and not standard name)
Renaming files with powershell (long and not standard name)

Time:12-07

I'm just getting to know 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.

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:

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

CodePudding user response:

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
}

CodePudding user response:

Regex expression explained on regex101.com, with test strings: regex101: build, test, and debug regex

(\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)
  • Related