There are multiple files in a directory that begin with prefix fgh
, for example:
fghfilea
fghfileb
fghfilec
I want to rename a
Another possible parameter expansion:
for f in fgh*; do mv -- "$f" "jkl${f:3}"; done
A generic script to run a sed
expression on a list of files (combines the sed solution with the rename solution):
#!/bin/sh
e=$1
shift
for f in $*; do
fNew=$(echo "$f" | sed "$e")
mv "$f" "$fNew";
done
Invoke by passing the script a sed
expression, and then any list of files, just like a version of rename:
script.sh 's/^fgh/jkl/' fgh*
rename might not be in every system. so if you don't have it, use the shell this example in bash shell
for f in fgh*; do mv "$f" "${f/fgh/xxx}";done
To install the Perl rename script:
sudo cpan install File::Rename
There are two renames as mentioned in the comments in Stephan202's answer.
Debian based distros have the Perl rename. Redhat/rpm distros have the C rename.
OS X doesn't have one installed by default (at least in 10.8), neither does Windows/Cygwin.
Using StringSolver tools (windows & Linux bash) which process by examples:
filter fghfilea ok fghreport ok notfghfile notok; mv --all --filter fghfilea jklfilea
It first computes a filter based on examples, where the input is the file names and the output (ok and notok, arbitrary strings). If filter had the option --auto or was invoked alone after this command, it would create a folder ok
and a folder notok
and push files respectively to them.
Then using the filter, the mv
command is a semi-automatic move which becomes automatic with the modifier --auto. Using the previous filter thanks to --filter, it finds a mapping from fghfilea
to jklfilea
and then applies it on all filtered files.
Other one-line solutions
Other equivalent ways of doing the same (each line is equivalent), so you can choose your favorite way of doing it.
filter fghfilea ok fghreport ok notfghfile notok; mv --filter fghfilea jklfilea; mv
filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter fghfilea "mv fghfilea jklfilea"
# Even better, automatically infers the file name
filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter "mv fghfilea jklfilea"
Multi-step solution
To carefully find if the commands are performing well, you can type the following:
filter fghfilea ok
filter fghfileb ok
filter fghfileb notok
and when you are confident that the filter is good, perform the first move:
mv fghfilea jklfilea
If you want to test, and use the previous filter, type:
mv --test --filter
If the transformation is not what you wanted (e.g. even with mv --explain
you see that something is wrong), you can type mv --clear
to restart moving files, or add more examples mv input1 input2
where input1 and input2 are other examples
When you are confident, just type
mv --filter
and voilà! All the renaming is done using the filter.
DISCLAIMER: I am a co-author of this work made for academic purposes. There might also be a bash-producing feature soon.
Here's a way to do it using command-line Groovy:
groovy -e 'new File(".").eachFileMatch(~/fgh.*/) {it.renameTo(it.name.replaceFirst("fgh", "jkl"))}'