2

I have a filename called "Ben_sucksatpowershell_2018_07_13_21_22_07.txt" I'm trying to rename that file to "b.20180713.b"

For the script I am writing I need to rename a series of these files, and the new name needs to be based off the original yyyy_MM_dd in the original file name

I get that I can I replace a chunk of the filename, but I don't know how to strip the underbars, or perform a multiple replace, or rename the file name in the same command. I am still new to powershell. I have been unable to find what I am looking for. I would appreciate guidance, on how to get what I'm seeking.

Foreach ($Slave in $Slaves)
{
$ProcessedPath = "\\$Server\Directory\Processed\"
$ProcessedSlave = "$ProcessedPath\$Slave\"
    If (!(Test-Path $ProcessedSlave))
    {
        Copy-Item -Path $Eticket -Destination $ProcessedPath -Force
        ren $Eticket  -NewName {$_.Name -replace ("Ben_sucksatpowershel_", "b.") | (".txt",".b")} #of course, this doesn't work though.

    }
    Else 
    {
         Write-Host "Potato"
    }
freakostudent
  • 105
  • 1
  • 2
  • 9

2 Answers2

2

Assuming you have a collection of filenames, in the example below the array $filenames, you can use a simple regular expression to match the the original yyyy_MM_dd, and then replace the underscores:

foreach ($filename in $filenames) {
    if ($filename -match '.*_(\d{4}_\d{2}_\d{2})_.*') {
        # $matches is a special / built-in PowerShell variable:
        # 1. $matches[0] => full regex match
        # 2. $matches[1] => first capturing group
        # 3. $matches[n] => nth capturing group
        $newName = "b.$($matches[1].Replace('_', '')).b";
        # remove -WhatIf when you're ready
        ren $filename  -NewName $newName -WhatIf;
    } else {
        Write-Warning "[$filename] does not match expected pattern"
    }
}
kuujinbo
  • 9,272
  • 3
  • 44
  • 57
2

To focus just on how a single -replace operation can achieve the desired transformation.:

$n = 'Ben_sucksatpowershell_2018_07_13_21_22_07.txt'
$n -replace '^Ben_sucksatpowershell_(\d{4})_(\d{2})_(\d{2})_.*?\.txt$', 'b.$1$2$3.b'

The above yields:

b.20180713.b
  • Note how the regex is designed to match the entire input (^...$), so that the replacement expression replaces it in full

  • Capture groups ((...)) are used to extract the substrings of interest, which are referred to in order in the replacement expression ($1 for the 1st capture group, $2 for the 2nd, ...); \d represents a single digit, and {<n>} represents exactly <n> repetitions).

  • For brevity, the remaining tokens in the input before the filename extension (_.*?) aren't matched explicitly, but you could easily add that.

Assuming that the rest of your code works as intended, modify your ren (Rename-Item) call as follows:

Rename-Item $Eticket -NewName {
  $_.Name -replace '^Ben_sucksatpowershell_(\d{4})_(\d{2})_(\d{2})_.*?\.txt$', 'b.$1$2$3.b'
}
mklement0
  • 382,024
  • 64
  • 607
  • 775