Sed One-Liner to Mass-Rename

Linux’s perl package has a command called “rename” which understands regular expressions.

Windows lacks that, of course. I’ll recreate it using sed, in a way that’s consistent across platforms…

It won’t spring to mind when you need it (unless you’re really familiar with sed), but the exercise is a decent excuse to demonstrate the oft-neglected hold buffer.
 

I’ll start by echoing a test string in and letting the shell catch what comes out (REGEX_HERE is a pseudocode placeholder).

ECHO zzz|
sed "h; REGEX_HERE ;s/.*/\x22&\x22/;x;s/.*/rename \x22&\x22/;G;s/\n/ /"

 
Here’s what sed’s doing step-by-step.

Command Pattern Hold
zzz
h
zzz
zzz
REGEX_HERE
NEW_NAME
zzz
s/.*/\x22&\x22/
"NEW_NAME"
zzz
x
zzz
"NEW_NAME"
s/.*/rename \x22&\x22/
rename "zzz"
"NEW_NAME"
G
rename "zzz"{newline}"NEW_NAME"
"NEW_NAME"
s/\n/ /
rename "zzz" "NEW_NAME"
"NEW_NAME"

 
“&” in a regex replacement means whatever string was matched.
“\x22″ is the hex character code for a double-quote, to avoid nesting complications.
“h” copies the pattern buffer into the hold.
“x” swaps pattern and hold.
“G” appends a newline and the hold to the end of the pattern buffer.
 
 
Replace REGEX_HERE with whatever you want done to each name, like “s/z/y/g” to globally change all z’s to y’s. Swap out the echo to “DIR /B”. And pipe sed into “CMD /Q”.

DIR /B |
sed "h; s/z/y/g ;s/.*/\x22&\x22/;x;s/.*/rename \x22&\x22/;G;s/\n/ /" |
CMD /Q

Everything in the current folder has been renamed.
 
 
Linux and OSX would use basically the same thing, but with mv, ls, and sh.

ls |
sed "h; s/z/y/g ;s/.*/\x22&\x22/;x;s/.*/mv \x22&\x22/;G;s/\n/ /" |
sh

 
 
Further reading: As plugged in an earlier sed romp, CatOnMat’s cheatsheet and Bruce Barnett’s guide are incredibly informative.

Tags: , ,

Leave a Reply