3

I'm trying to rename all the files in a given directory so that they have the sequential format 001a.jpg, 001b.jpg, 002a.jpg etc.

I have tried:

$c=1
get-childitem * | foreach {
if($c/2=[int]($c/2)){
rename-item -NewName {($c-1) + 'b.jpg'} else rename-item - NewName {$c + 'a.jpg'}}$c++} - whatif

But I am getting "the assignment operator is not valid".

The = in the third line is obviously not supposed to be an assignment operator. I just want to check whether the counter is on an even number. I found -ne for not equal to but PS didn't seem to like the -.

I am not sure about the syntax of the new names but the parser doesn't get that far ATM.

Grateful for any pointers.

Edit: I've just realised the numbers would skip but I can fix that once I understand the problem with what I already have.

4
  • 1
    Leave spaces around comparison operators -eq, -ne etc, otherwise the dash is seen as a minus to the equasion $c/2 Commented Nov 14, 2020 at 20:34
  • 2
    P.S. to test if a number is odd, it might be quicker to do if ($c % 2) or if ($c -band 1) Commented Nov 14, 2020 at 20:46
  • Thanks a lot. I think the comparison operator is OK now but there seems to a problem with the foreach. I am getting "ForEach-Object : Cannot bind parameter 'RemainingScripts'. Cannot convert the "-" value of type "System.String" to type "System.Management.Automation.ScriptBlock"." Commented Nov 14, 2020 at 20:49
  • Because of your edit "I can fix that once I understand the problem with what I already have" I only addressed the comparison problem you had. Petty you didn't ask to review/repair all of your code.. Commented Nov 14, 2020 at 21:19

2 Answers 2

3

As commented, if you do not leave spaces around the -eq or -ne operators, PowerShell will interpret the dash as belonging to the math, so

if($c/2-ne[int]($c/2))

Will fail.

Also, to test if a number is odd, it is probably quicker to do if ($c % 2) or if ($c -band 1).

Use -not to test for even numbers.

Sign up to request clarification or add additional context in comments.

Comments

1

Several things you need to know (some are just recommendations):

  1. Every if-else branch requires curly brackets
  2. If you do not input the items to Rename-Item via the pipeline, you have to specify the path
  3. If you specify the path for Rename-Item, you cannot use a script block for -NewName
  4. You cannot use + if the left operand is int and the right is string, because it would be interpreted as addition and requires two numbers.
  5. You cannot use the -WhatIf switch on the whole construct, but only individual commands
  6. It will suffice to use the command only once, and use the if-else only to set the new name
  7. You can simplify your condition using the modulus operator % (as explained in other answers and comments)
  8. You can use the -Begin parameter for initialization
  9. The * for Get-ChildItem is not necessary

Here is the updated code:

Get-ChildItem | foreach -Begin { $c = 1 } -Process {
    if ($c % 2) {
        $newName = "${c}a.jpg"
    }
    else {
        $newName = "$($c-1)b.jpg"
    }
    Rename-Item -LiteralPath $_.FullName -NewName $newName -WhatIf
    $c++
}

Here is an even shorter version, that pipes directly into Rename-Item

$c = 0
Get-ChildItem |
  Rename-Item -NewName {if (++$script:c % 2) {"${c}a.jpg"} else {"$($c-1)b.jpg"}} -WhatIf

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.