Pregunta

I have no problem adding sequential prefixes to filenames. The following works great on the top directory in question.

$path="E:\path\newtest1"
$count=4000
Get-ChildItem $path -recurse | Where-Object {!$_.PSIsContainer -and $_.Name -NotMatch '^\d{4}\s+'}  | ForEach -Process {Rename-Item $_ -NewName ("$count " + $_.name -f $count++) -whatif}

BUT if there are files in subfolders within the top directory, these are all completely missed. Whatif reports that for any deeper file it "does not exist".

I have tried the following, based on looking at some pages on other recursion problems, but as you can probably guess I have no clue what it is doing. Whatif shows that it does at least pickup and rename all the files. But the following does it too much and makes multiple copies of each file with each number:

$path="E:\path\newtest1"
$count=4000
Get-ChildItem  -recurse | ForEach-Object {  Get-ChildItem $path | Rename-item -NewName    ("$count " + $_.Basename  -f $count++) -whatif}

Really keen to get some guidance on how to get the first of these two snippets to work to find all files in all subdirectories and rename them with sequential number prepended.

¿Fue útil?

Solución

Try it like so:

Get-ChildItem $path -recurse -file | Where Name -NotMatch '^\d{4}\s+' | 
    Rename-Item -NewName {"{0} $($_.name)" -f $count++} -whatif

When you supply $_ as an argument (not a pipeline object), that gets assigned to the Path parameter which is of type string. PowerShell tries to convert that FileInfo object to a string but unfortunately the "ToString()" representation of files in nested folders is just the filename and not the full path. You can see this by executing:

Get-ChildItem $path -recurse -file | Where Name -NotMatch '^\d{4}\s+' | ForEach {"$_"}

The solution is either to A) pipe the object into Rename-Item or B) use the FullName property e.g. Rename-Item -LiteralPath $_.FullName ....

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top