In bash, it can be done as follows:
for i in *; do echo $i | awk -F'[_.]' '{print $1"_"$2"_"$4"_"$3 }' ; done
This command first finds all files in the current directory, then feeds these names (it assumes without checking that there are three underscores and a . in these file names) to awk, which rearranges them in the order you wish.
The only tricky part is -F'[_.]'
The option -F' '
is used to identify the delimiter between different fields, and in this last case the delimiter takes on its default value, a space. But the option -F'[_.]'
defines a character class of interchangeable elements, in this case underscore and dot, which can be used at will as delimiters.
Edit:
Ok, since this works, without actually moving anything, we can now implement the actual act of renaming the files:
for i in *; do ni=$(echo $i | awk -F'[_.]' '{print $1"_"$2"_"$4"_"$3"."$5 }') && mv "$i" "$ni" ; done