I have 5 variables and I have 3 files.
$NumOne = Read-Host 'Enter four digit numone'
$NumTwo = Read-Host = 'Enter two digit numtwo'
$sdataJRN= $NumOne + $NumTwo + "00" + ".jrn"
$sdataJNM = $NumOne + $NumTwo + "00" + ".jnm"
$sdataTXN = $NumOne + $NumTwo + "00" + ".txn"
Right now the three files are 06540200.jnm and jrn and txn respectively.
I want to rename each of these files. Instead of being 00 at the end I want 99. 06540299 jrn jnm txn
I am doing this with the following lines:
Rename-Item $sdataJRN -NewName $NumOne,$NumTwo,"99",".jrn"
Rename-Item $sdataJNM -NewName $NumOne,$NumTwo,"99",".jnm"
Rename-Item $sdataTXN -NewName $NumOne,$NumTwo,"99",".txn"
This returns an error.
Rename-Item : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'NewName'. Specified method is not supported. At line:1 char:34 + Rename-Item $sdataJRN[0] -NewName <<<< $storeNum,$regNum,"99",".jrn" + CategoryInfo : InvalidArgument: (:) [Rename-Item], ParameterBindingException + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.RenameItemCommand
What you're looking for is a delay-bind script block, which allows you to derive a parameter value from each input object:
Note: As in your code, the assumption is that the input files are located in the current directory.
$sdataJRN, $sdataJNM, $sdataTXN |
Rename-Item -NewName { $_ -replace '00\.([^.]+)$', '99.$1' }
{ ... }
is a delay-bind script block that is evaluated for each input object, and inside of it automatic variable $_
refers to the input object at hand.
The -replace
operator operates on regexes (regular expressions):
00\.([^.]+)$
matches 00
before a literal .
(\.
), followed by one ore more characters that aren't literal .
([^.]
) at the end of the string ($
).
By enclosing [^.]+
in (...)
, the match - the filename extension, in this case - is captured so that it can be referenced in the replacement operand as $1
, i.e., the 1st (and in this case only) capture group.
Replacement operand 99.$1
then replaces everything the regex matched with literal 99.
, followed by the value of $1
, i.e., the value of the 1st capture group, i.e., the input filename extension.
As for what you tried:
Rename-Item $sdataJRN -NewName $NumOne,$NumTwo,"99",".jrn"
$NumOne,$NumTwo,"99",".jrn"
is not a string-concatenation operation, it creates a 4-element array, due to use of ,
, PowerShell's array-construction operator.
Since the -NewName
operator is [string]
-typed - i.e., a single string, trying to pass an array fails.
For a specific input name you could have used an expandable string to synthesize the -NewName
argument:
Rename-Item $sdataJRN -NewName "${NumOne}${NumTwo}99.jrn"
That said, the delay-bind solution above offers more flexibility.