Maax
Maax

Reputation: 33

Using Powershell, how can I change filename recursively in a way to replace '0' with '-' in specific part of file name?

Directory Structure:

C:\C4144754951436B4\RECORDS\7005\2017\12\20\1000\1234#20171220#6359444#0500000000#Maaz0Bin0Mah.Sid0Asr.wav

Files exist only in last folder (1000 in the above case)

Current File Name

1234#20171220#6359444#0500000000#Maaz0Bin0Mah.Sid0Asr.wav

Required File Name

I need to replace any 0 after last # with - so that result becomes:

1234#20171220#6359444#0500000000#Maaz-Bin-Mah.Sid-Asr.wav

I tried but couldn't make it work with a single liner, recursively.

PS H:\> $test

1234#20171220#6359444#0500000000#Maaz0Bin0Mah.Sid0Asr.wav

PS H:\> $ol=($test -split "#")[0]+'#'+($test -split "#")[1]+'#'+($test -split "#")[2]+'#'+($test -split "#")[3]+'#'+($te
st -split "#")[4].replace('0','-')

PS H:\> $ol

1234#20171220#6359444#0500000000#Maaz-Bin-Mah.Sid-Asr.wav

How can I achieve the same results using Get-ChildItem?

Upvotes: 1

Views: 88

Answers (3)

Ingemar
Ingemar

Reputation: 139

Using regular expressions will solve your problem. Not a one-liner though :)

$currentFileName = '1234#20171220#6359444#0500000000#Maaz0Bin0Mah.Sid0Asr.wav'
$currentFileName -match '(.*#)(.*)'
$newFileName = $Matches[1] + $Matches[2].Replace('0', '-')

$currentFileName, $newFileName

Will output

1234#20171220#6359444#0500000000#Maaz0Bin0Mah.Sid0Asr.wav
1234#20171220#6359444#0500000000#Maaz-Bin-Mah.Sid-Asr.wav

Upvotes: 1

ctwheels
ctwheels

Reputation: 22817

Code

See code in use here

$str = "C:\C4144754951436B4\RECORDS\7005\2017\12\20\1000\1234#20171220#6359444#0500000000#Maaz0Bin0Mah.Sid0Asr.wav"
$a = $str.Substring(0, $str.LastIndexOf("#") + 1) + $str.Split("#")[-1].Replace("0", "-")
Write-Host $a

Explanation

The code is:

  1. Removing everything after the last occurrence of #
  2. Splitting the original string on #, getting the last element, then replacing all instances of 0 with -
  3. Concatenating 1. and 2. above

Upvotes: 0

Bacon Bits
Bacon Bits

Reputation: 32170

$FullName = 'C:\C4144754951436B4\RECORDS\7005\2017\12\20\1000\1234#20171220#6359444#0500000000#Maaz0Bin0Mah.Sid0Asr.wav'
$NewFullName = $FullName.Substring(0, $FullName.LastIndexOf('#')) + $FullName.Substring($FullName.LastIndexOf('#')).Replace('0','-')

If you want it in a pipeline with Rename-Item:

Get-ChildItem -Path $Path -Recurse -File | 
    Where-Object {
        $_.Name.LastIndexOf('#') -ge 0;
    } | 
    ForEach-Object {
        $NewName = $_.Name.Substring(0, $_.Name.LastIndexOf('#')) + $_.Name.Substring($_.Name.LastIndexOf('#')).Replace('0','-');
        Rename-Item -Path $_.FullName -NewName $NewName;
    }

The Where-Object is necessary because Substring requires positive arguments and if the # character isn't present, then LastIndexOf returns -1.

I suppose you can condense it to:

Get-ChildItem -Path $Path -Recurse -File | 
    Where-Object {
        $_.Name.LastIndexOf('#') -ge 0;
    } |
    Rename-Item -NewName ($_.Name.Substring(0, $_.Name.LastIndexOf('#')) + $_.Name.Substring($_.Name.LastIndexOf('#')).Replace('0','-'));

But I find that much harder to read.

Upvotes: 1

Related Questions