rename - Weird behaviour in PowerShell bulk file renaming -
i'm new powershell , try rename 120 files in folder , encounter weird behavior.
what have files named 0001.txt, 0002.txt, ... 0120.txt total of 120 files. want add 'a' in front of each of file name. came command:
ls | ren -newname {$_.name -replace '(\d+)','a$1'}
but after execution, numerous error this:
"the specified path, file name, or both long. qualified file name must less 260"
and when folder, file names from
aaaaaaaaaaaaaaaaaaaaaaaaa(repeat until hit system limit on path length)....a0001.txt ... ... ... aaaaaaaaaaaaaaaaaaaaaaaaa(repeat until hit system limit on path length)....a0120.txt
upon further inspection using -cf switch, turns out powershell attempts renaming process recursively. after first pass of renaming 120 files, went on again applying command a0001.txt adding 'a' in front of filename. , went on until hit path length limit , reported error.
can tell me if there wrong in renaming command?
pipe foreach-object (shorthand %{ }) mass-rename files. if want prepend letter a each filename, don't need regex, need this:
get-childitem | %{rename-item $_ ('a' + $_.name)}
using preferred aliases:
ls | %{ren $_ ('a' + $_.name)}
to regex, it's simpler use ($_.name -replace '^','a')
. if reason using regex have other files in directory , want rename files named string of digits , .txt extension, note regex you're using prepend a string of consecutive digits. example, agent007.txt renamed agenta007.txt. should have regex match format want: '^(\d+)\.txt'
.
also note using regex replace in -newname argument, you're renaming each file doesn't match regex same name has. not big deal 120 files, i'd filter file listing in advance:
get-childitem | ?{$_ -match '^(\d+)\.txt'} | %{rename-item $_ ('a' + $_.name)}
update: there appears bug in powershell 3.0 can cause bulk file renaming fail under conditions. if files renamed piping directory listing rename-item, file that's renamed that's alphabetically higher current name reprocessed new name it's encountered later in directory listing. can cause same files repeatedly renamed until length of full path exceeds 260 character maximum , error thrown.
note, example, if letter a appended rather prepended, there no problem. works number of files:
get-childitem | %{rename-item $_ ($_.name + 'a')}
if files named b0001, b0002, etc., , letter a prepended, repeated reprocessing not occur. however, if letter c prepended, occur.
the following command adds single a beginning of number of files if names begin with b:
get-childitem | %{rename-item $_ ('a' + $_.name)}
given same files, names beginning b, following command prepends letter c repeatedly until length limit reached:
get-childitem | %{rename-item $_ ('c' + $_.name)}
this happens listing containing number of files or higher. op said doesn't have problem if reduces number of files less 20. found threshold 37 (with 36 files or less, reprocessing doesn't happen). haven't determined yet whether number same applicable cases or depends on more specific factors.
i'll elaborate on later, , submit bug report microsoft once i've determined parameters of problem more specifically.
workaround: filter listing get-childitem where-object such new filenames excluded. last version of command above before update section works in powershell 3.0. presumably, renamed files reintroduced pipeline new names , processed 1 more time, because new names don't match filter ?{$_ -match '^(\d+)\.txt'}
, not renamed on second pass through pipeline , not reprocessed again.