New Solution
There is an extremely simple solution using JREN.BAT, my new hybrid JScript/batch command line utility for renaming files and folders via regular expression search and replace.
Only rename files with one underscore:
jren "^[^_]+_([^_]+\.png)$" "$1" /s /i
Preserve everything after the first underscore:
jren "^.*?_" "" /s /fm "*.png"
Preserve everything after the last underscore:
jren "^.*_" "" /s /fm "*.png"
=========================================================
Original Answer
This can be done using a hybrid JScript/batch utility called REPL.BAT that performs regex search and replace on stdin and writes the result to stdout. All the solutions below assume REPL.BAT is somewhere within your PATH.
I intentionally put ECHO ON so that you get a log of the executed rename commands. This is especially important if you get a name collision: two different starting names could both collapse to the same new name. Only the first rename will succeed - the second will fail with an error message.
I have three solutions that differ only in how they handle names that contain more than 1 _
character.
This solution will only rename files that have exactly one _
in the name (disregarding extension). A name like a_b_c_d.txt
would be ignored.
@echo on&@for /f "tokens=1,2 delims=*" %%A in (
'2^>nul dir /b /s /a-d *_* ^| repl ".*\\[^_\\]*_([^_\\]*\.[^.\\]*)$" "$&*$1" a'
) do ren "%%A" "%%B"
The next solution will preserve the name after the last _
. A name like a_b_c_d.txt
would become d.txt
@echo on&@for /f "tokens=1,2 delims=*" %%A in (
'2^>nul dir /b /s /a-d *_* ^| repl ".*_([^\\_.]*\.[^.\\]*)$" "$&*$1" a'
) do echo ren "%%A" "%%B"
This last solution will preserve the name after the first _
. A name like a_b_c_d.txt
would become b_c_d.txt
. This should give the same result as the Endoro answer.
@echo on&@for /f "tokens=1,2 delims=*" %%A in (
'2^>nul dir /b /s /a-d *_* ^| repl ".*\\[^\\]*?_([^\\]*\.[^.\\]*)$" "$&*$1" a'
) do echo ren "%%A" "%%B"