Needed to remove spaces from filenames, so here we are 🙂
for file in *.mp3; do mv "$file" `echo $file | sed -e 's/ */_/g' -e 's/_-_/-/g'`; doneor replace all spaces by _ using perl
ls *.bed |perl -ne 'use File::Copy;chomp;$old=$_;s/\s+/_/g;move($old,$_);'remove underscores
rename 's/2012mp3/2012/' *.mp3Remove the letters mp3 from middle fo filename say in case of 123-20121mp3.mp3 or some such
for i in *.mp3; do mv $i ${i//[[:punct:]]/}; doneremove punctuations from filename. WARNING it will also remove the . from extension names.
for foobar in *.mp3 ; dotemp=`echo "$foobar" | cut -c 2-`mv "$foobar" "$temp" ;doneremove first X characters from file name. change the 2 to any number to change the first characters removed. the formula for that is 1 + actual number. make sure to change the extension.
rename 's/1234/12-34/' *.mp3remove some character from the middle of the file name, in this case the dash ( – ).
When Things Go Sideways
That punctuation removal one-liner up there? It’ll nuke your file extension too. You lose track01.mp3 and get track01mp3 — a useless blob your media player won’t touch. The fix is either being surgical about what you strip, or reconstructing the extension afterward. Surgical is easier:
# Strip punctuation from the base name only, leave the extension alonefor f in *.mp3; do base="${f%.*}" ext="${f##*.}" clean="${base//[[:punct:]]/}" mv "$f" "${clean}.${ext}"doneThe ${f%.*} strips everything after the last dot (the extension). ${f##*.} grabs just the extension. You glue them back together. Simple, doesn’t blow up your files.
The rename Command Has Two Different Versions
This trips people up constantly. rename 's/foo/bar/' *.mp3 works fine on Debian/Ubuntu where rename is the Perl-based File::Rename. On Red Hat/Arch/Fedora it’s rename from to files — a completely different syntax with no regex support.
# Check which one you haverename --version# Perl version says: /usr/bin/rename using File::Rename version X.XX# util-linux version says: rename from to file...If you’re on the util-linux version and need regex, either install perl-rename (some distros package it that way) or just write the bash loop. The bash loop always works. Everywhere.
Bulk Cleanup for Mixed Filenames
Real world scenario: you’ve downloaded a folder of files that have spaces, parentheses, weird unicode dashes, and numbers in the name. One pass of sed won’t cut it. Here’s a chained approach that handles most of the mess in one shot:
for f in *; do [ -f "$f" ] || continue # skip directories newname=$(echo "$f" \ | sed 's/ /_/g' \ | sed 's/[(){}]//g' \ | sed 's/\[//g; s/\]//g' \ | sed 's/--*/-/g' \ | sed 's/__*/_/g') [ "$f" != "$newname" ] && mv -- "$f" "$newname"doneThe [ -f "$f" ] || continue guard matters — without it you’ll try to mv directories too. The [ "$f" != "$newname" ] check skips files that didn’t need renaming, so you don’t get a wall of redundant mv calls cluttering your terminal.
Dry Run First, Always
Before running any bulk rename on a directory you care about, swap the mv for echo and see what would happen:
for file in *.mp3; do newname=$(echo "$file" | sed -e 's/ */_/g' -e 's/_-_/-/g') echo "mv \"$file\" \"$newname\""doneYou’re just printing the commands instead of running them. If the output looks wrong, you’ve saved yourself a recovery session. If it looks right, remove the echo and run for real. Your 2 AM self will appreciate not having to fish files out of the trash.
Unicode and Special Characters
If your filenames came from Windows, macOS, or some ancient MP3 downloader, you might have em-dashes (—), en-dashes (–), or non-breaking spaces mixed in that look identical to regular dashes and spaces in your terminal but aren’t. sed 's/ /_/g' won’t touch them.
# Nuke anything that isn't alphanumeric, dot, dash, or underscorefor f in *; do [ -f "$f" ] || continue newname=$(echo "$f" | tr -dc 'a-zA-Z0-9._-' | sed 's/--*/-/g') [ "$f" != "$newname" ] && mv -- "$f" "$newname"donetr -dc 'a-zA-Z0-9._-' deletes every character that isn’t in that set. It’s a blunt instrument — you lose accented characters too — but for filenames going into a script or a web server, boring ASCII is exactly what you want.
When the Target File Already Exists
One scenario that bites people more than it should: you run your rename loop and halfway through it errors out because the destination filename already exists. Say you’ve got Track 01.mp3 and Track_01.mp3 sitting in the same folder — after normalizing spaces to underscores, both want to be Track_01.mp3. The second mv just silently overwrites the first on most systems.
# Safe rename loop that skips collisions instead of overwritingfor file in *.mp3; do newname=$(echo "$file" | sed -e 's/ */_/g' -e 's/_-_/-/g') if [ "$file" = "$newname" ]; then continue # nothing to rename fi if [ -e "$newname" ]; then echo "SKIP: '$newname' already exists (would overwrite '$file')" continue fi mv -- "$file" "$newname"doneThe [ -e "$newname" ] check catches the collision before mv does something regrettable. You get a log of what was skipped, and you can decide manually — keep one, merge them, or rename to Track_01_b.mp3. Either way, you’re not losing data silently.
If you want automatic deduplication — say you’re certain the duplicate content is identical — you can skip both files and deal with them later, or generate a unique suffix on the fly:
# Auto-suffix collisions: Track_01.mp3 → Track_01_1.mp3, Track_01_2.mp3, etc.counter=1while [ -e "${newname%.*}_${counter}.${newname##*.}" ]; do ((counter++))donenewname="${newname%.*}_${counter}.${newname##*.}"mv -- "$file" "$newname"Clunky, but better than a mystery missing file at 2 AM.