0

I want to know which command I can use to rename files like this.

Let's say, for instance, the old filenames are:

0_predict-1-500.png
0_predict-2-500.png
0_predict-3-500.png
1_predict-1-500.png
1_predict-2-500.png
1_predict-3-500.png
2_predict-1-500.png
...so on...

What I am expecting is to extract them with the format like {filename}_predict-{times}-{rounds}.png, then I can replace it into another pattern, for example, {filename}.png-result-{times}.png.

So, the aforementioned filenames will be changed to match the pattern:

0.png-result-1.png
0.png-result-2.png
0.png-result-3.png
1.png-result-1.png
1.png-result-2.png
1.png-result-3.png
2.png-result-1.png
...so on...

Does anyone has the Linux command/tool to do thing like this? I don't wanna write the Python script to complete this.

0

5 Answers 5

1

I have just found out that there is a tool that can easily manipulate filenames in GNU/Linux which is mmv. It is quite much easier than the posted answers.

In my case,

mmv "*_predict-*-*.png" "#1.png-result-#2.png"

It tries to substitute each part with a wildcard pattern, consequently, we can re-use the part with #1, #2, and so on.

0

With the help of rename command you can edit it, I am assuming that all files are in same directory and you want to rename all .png files.:

find -name \*.png -exec sh -c 'x=$( rename -v 's/_predict/.png-result/g' $0 ) ;  rename  's/-500//g' "${x##*\./}" ;' {} \;

Run this command in that directory where files are.

So basically it runs two times rename command first one to remove _predict and second one to remove -500.

Here I used x=$( rename -v 's/_predict/.png-result/g' $0 ) because after first change in the file name, I stored this new name in variable x and then used this value for second modification.

Command rename 's/-500//g' "${x##*\./}" ; is used because value of x is like ./0_predict-1-500.png renamed as ./0.png-result-1-500.png so I just want 0.png-result-1-500.png and ${x##*\./} will do that.

0

Try also

$ for FN in *.png; do IFS="_-." read F P T R X <<< "$FN"; echo mv "$FN" "$F.$X-result-$T.$X"; done
mv 0_predict-1-500.png 0.png-result-1.png
mv 0_predict-2-500.png 0.png-result-2.png
mv 0_predict-3-500.png 0.png-result-3.png
mv 1_predict-1-500.png 1.png-result-1.png
mv 1_predict-2-500.png 1.png-result-2.png
mv 1_predict-3-500.png 1.png-result-3.png
mv 2_predict-1-500.png 2.png-result-1.png

and remove the echo if happy with the result. We're looping through the target files, read the file name components using an adapted IFS variable and a "here string", and then reassemble the components to form the desired final file name for the mv command.

0

To add yet another variation, this uses the bash shell's =~ pattern matching operator in the [[ test command to pick out the elements to be rearranged:

for f in ./*_predict-*-*.png
do
  [[ $f =~ ^\./([[:digit:]]+)_predict-([[:digit:]]+)-([[:digit:]]+).png ]]
  echo mv -- "$f" "${BASH_REMATCH[1]}.png-result-${BASH_REMATCH[2]}.png"
done

Remove the echo if the results look correct.

0

Mention all the files in a file which needs to be renamed

awk  '{print "mv -v" " " $1 " " substr($1,1,1)".png-result-"substr($1,11,1)".png"}' filename |sh


I have mentioned -v for verbose mode

This is how it shows output for renaming

awk  '{print "mv -v" " " $1 " " substr($1,1,1)".png-result-"substr($1,11,1)".png"}' filename|sh

`0_predict-1-500.png' -> `0.png-result-1.png'
`0_predict-2-500.png' -> `0.png-result-2.png'
`0_predict-3-500.png' -> `0.png-result-3.png'
`1_predict-1-500.png' -> `1.png-result-1.png'
`1_predict-2-500.png' -> `1.png-result-2.png'
`1_predict-3-500.png' -> `1.png-result-3.png'
`2_predict-1-500.png' -> `2.png-result-1.png'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .