PowerShell按原文件顺序批量替换文件名指定字符
Hey there, let's tackle your PowerShell renaming issue. The root cause of your lost file order is that dir (aka Get-ChildItem) doesn't guarantee a consistent default sort order—it depends on how your file system returns files, and string-based sorting can mess up numeric sequences (like file10 coming before file2). Here's how to fix this while making the operation more efficient:
Step 1: Lock in Your Desired File Order
First, explicitly sort your files to match the order you want. Pick one of these sorting options based on your needs:
- Original filename string sort: Use if your filenames follow a consistent string pattern that sorts logically.
- Natural numeric sort: Use if your filenames have numbers and you want
file1,file2,file10to sort in that order (notfile1,file10,file2). - Creation/modification time: Use if you want to sort based on when files were created or edited.
Step 2: Efficient, Order-Preserving Rename Code
Here's a refined script that fixes the order issue and targets exactly the "60-" followed by 3 characters for replacement:
# Set your starting number for the sequence $startingNumber = 1 # Get files and sort them (choose the Sort-Object line that fits your needs) $files = Get-ChildItem * | # Option 1: Sort by original filename (string sort) Sort-Object Name # Option 2: Natural numeric sort for filenames with numbers # Sort-Object { [regex]::Replace($_.Name, '\d+', { $args[0].Value.PadLeft(20) }) } # Option 3: Sort by creation time # Sort-Object CreationTime # Option 4: Sort by last modified time # Sort-Object LastWriteTime # Rename files while preserving order $files | ForEach-Object -Begin { $currentNum = $startingNumber } -Process { # Replace "60-" followed by 3 characters with "60-XXX" where XXX is the incrementing 3-digit number # If the 3 characters are always digits, use '\d{3}' instead of '.{3}' $newFileName = $_.Name -replace '(60-).{3}', "`$1$($currentNum.ToString('D3'))" # Use -WhatIf to preview changes first! Remove it when you're ready to apply $_ | Rename-Item -NewName $newFileName -WhatIf }
Key Improvements Over Your Original Code:
- Explicit sorting: No more random file order—you control exactly how files are sequenced.
- Single file system scan:
Get-ChildItemruns once instead of multiple times, making the operation faster, especially with lots of files. - Precise replacement: The regex targets only the "60-" + 3 character segment, so you don't have to rebuild the entire filename from scratch (unless you want to, but this is more efficient).
Pro Tips:
- Always use
-WhatIffirst to preview the new filenames—this prevents accidental renames you can't undo. - If you need to replace all instances of "60-" followed by 3 characters (not just the first), add the
'All'flag to the replace:$_.Name -replace '(60-).{3}', "$1$($currentNum.ToString('D3'))", 'All'` - Adjust the regex if the 3 characters aren't generic—for example, if they're always uppercase letters, use
[A-Z]{3}instead of.{3}.
内容的提问来源于stack exchange,提问作者Romaine Veggum
相关产品推荐
相关产品推荐

