1

I have a PowerShell code that renaming the files name, and just cutting some letters from the end of the file name. Now I am trying to rename it like this: For example my file name is "a_b_c_d_e_f.txt", so I want to change it to "a_b_c.txt". Any Ideas?

Get-ChildItem 'C:\Users\xxx\Projects\testfiles' -filter *.txt |
  Rename-Item -NewName {$_.name.substring(0,$_.BaseName.length-9) + $_.Extension}
mklement0
  • 382,024
  • 64
  • 607
  • 775
David
  • 239
  • 1
  • 2
  • 12
  • You actually forgot to explain what's wrong with your code. Why are you mixing the properties `Name` and `BaseName`? What exactly do you mean with *cutting some letters from the end*? How many letters do you want to remove? What's when there are not enough letters? – Olaf May 14 '23 at 12:43
  • Use Regex : $pattern = '^(?[a-z]_[a-z]_[a-z])(?[^.]+)(?.txt)'; $results = "a_b_c_d_e_f.txt" -replace $pattern, '${keep}${extension}'; $results – jdweng May 14 '23 at 13:16

3 Answers3

2

I'd use a helper function for this:

function getNewName($basename, $extension){
  $s = $basename -split "_"
  $n = ($s[0..($s.Length-4)]) -join "_"
  return "$n"+$extension
}

Usage:

> new-item "a_b_c_d_e_f.txt"; 
> Get-ChildItem '.' -filter *.txt | rename-item -NewName {getNewName $_.Basename $_.Extension}

> Get-Item *.txt
a_b_c.txt

the logic of the helper function is to split on _ and join all but the last three elements (in this case, d, e, and f).

Paolo
  • 21,270
  • 6
  • 38
  • 69
2

Use regex -replace

Get-ChildItem -Path 'C:\Users\xxx\Projects\testfiles' -Filter '*_*_*_*.txt' -File |
Rename-Item -NewName {'{0}{1}' -f ($_.BaseName -replace '_[^_]+_[^_]+_[^_]+$'), $_.Extension}
Theo
  • 57,719
  • 8
  • 24
  • 41
1

To complement Paolo's helpful -split answer with a PowerShell (Core) 7+ solution, where the -split operator now accepts negative indices, for splitting from the end of a string:

Get-ChildItem C:\Users\xxx\Projects\testfiles -Filter *.txt | 
  Rename-Item -NewName {
    ($_.BaseName -split '_', -4)[0] + $_.Extension
  } -WhatIf

The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf and re-execute once you're sure the operation will do what you want.

  • -split '_', -4 splits the input file name into substrings by separator _, extracting up to 4 tokens from the end of the string, and returning whatever remains at the front of the input string as the first element.

    • E.g., 'a_b_c_d_e_f' is split into prefix 'a_b_c' and token array @('d', 'e', 'f') (which we're not interested in here).
  • + $_.Extension appends the existing extension to the resulting name, resulting in 'a_b_c.txt'

Note:

  • File names that contain no _ instances are left as-is (no renaming occurs).

  • File names with only 1 to 2 _ instances are renamed to the prefix before their first _; e.g. 'a_b_c.txt' becomes 'a.txt'

  • Individual rename operations may fail, if the new, shortened names result in duplicates.

mklement0
  • 382,024
  • 64
  • 607
  • 775