There are a lot of ways to do this. Here is one command that should work for your example:
for oldname in *; do
newname="$(echo "${oldname}" | grep -Po 'ID\w?\d+' | tr A-Z a-z).txt" \
&& mv -i "${oldname}" "${newname}";
done
That example used Perl-compatible regular-expressions which it appears your grep
does not support. Here is an alternative using basic regular expressions:
for oldname in *; do
newname="$(echo "${oldname}" | grep -o 'ID[A-Z]\?[0-9]\+' | tr A-Z a-z).txt" \
&& mv -i "${oldname}" "${newname}";
done
A more detailed explanation follows.
The expression for oldname in *
uses a globbing-pattern/wildcard to iterate over the files in your current directory and stores each name in the oldname
variable. To test this you could run the following:
for oldname in *; do echo "${oldname}"; done
Then we use grep
to extract the part of the file-name you want to keep. The -P
option flag tells grep
to use Perl-compatible regular expressions (not really necessary in this situation) and the -o
flag tells grep
to extract only the matching substring (instead of printing the entire string). The \w?
pattern matches an option single character (a "word" character) and the \d+
pattern matches one or more digits. We can test out the regular expression like this:
for oldname in *; do echo "${oldname}" | grep -Po 'ID\w?\d+'; done
Then we use tr
to convert uppercase characters to lowercase:
for oldname in *; do echo "${oldname}" | grep -Po 'ID\w?\d+' | tr A-Z a-z; done
The next step is to use command substitution to assign this string to a variable and then print the result:
for oldname in *; do
newname="$(echo "${oldname}" | grep -Po 'ID\w?\d+' | tr A-Z a-z)" && echo "${newname}"
done
Then we add in the ".txt" file-extension:
for oldname in *; do
newname="$(echo "${oldname}" | grep -Po 'ID\w?\d+' | tr A-Z a-z).txt" && echo "${newname}"
done
We can run this command as a sanity-check to make sure we're getting the expected results. Once we're satisfied we replace the echo
command with a mv
command:
for oldname in *; do
newname="$(echo "${oldname}" | grep -Po 'ID\w?\d+' | tr A-Z a-z).txt" \
&& mv -i "${oldname}" "${newname}";
done
_213_
and_215_
always fixed (the same) for all filenames?