This should do:
for i in *.mp3; do
[[ "$i" = *_* ]] && mv -nv -- "$i" "${i//_/ }"
done
- The test
[[ "$i" = *_* ]]
tests if file name contains any underscore and if it does, will mv
the file, where "${i//_/ }"
expands to i
where all the underscores have been replaced with a space (see shell parameter expansions).
- The option
-n
to mv
means no clobber
: will not overwrite any existent file (quite safe). Optional.
- The option
-v
to mv
is for verbose
: will say what it's doing (if you want to see what's happening). Very optional.
- The
--
is here to tell mv
that the arguments will start right here. This is always good practice, as if a file name starts with a -
, mv
will try to interpret it as an option, and your script will fail. Very good practice.
Another comment: When using globs (i.e., for i in *.mp3
), it's always very good to either set shopt -s nullglob
or shopt -s failglob
. The former will make *.mp3
expand to nothing if no files match the pattern (so the loop will not be executed), the latter will explicitly raise an error. Without these options, if no files matching *.mp3
are present, the code inside loop will be executed with i
having the verbatim value *.mp3
which can cause problems. (well, there won't be any problems here because of the guard [[ "$i" = *_* ]]
, but it's a good habit to always use either option).
Hope this helps!