0

I have a directory in which I have lot of files in this format only. Below are just examples for two of my files.

file_948_of_2000_push_data_12345.log
file_950_of_2000_push_data_12345.log

As you can see only difference is this file number 948 and 950. Now I want to rename all these files in this particular format as shown below:

files_948.log
files_950.log

What is the best way I can do this?

2 Answers2

2

Using shell parameter expansion

$ for f in *.log; do g="${f/#file_/}"; echo mv -- "$f" "files_${g%%_*}.log"; done
mv -- file_948_of_2000_push_data_12345.log files_948.log
mv -- file_950_of_2000_push_data_12345.log files_950.log

Using the perl-based prename or rename command

$ prename -n -- 's/^(.*?)_(.*?)_.*\.log$/$1s_$2.log/' *.log
file_948_of_2000_push_data_12345.log renamed as files_948.log
file_950_of_2000_push_data_12345.log renamed as files_950.log

Using mmv

$ mmv -n '*_*_*.log' '#1s_#2.log'
file_948_of_2000_push_data_12345.log -> files_948.log
file_950_of_2000_push_data_12345.log -> files_950.log

Remove the -n or echo as appropriate.

steeldriver
  • 81,074
1

You can try this command:

  ls -C1 file*log |  perl -ane 'chomp;$d=$_; s/^(\w+?)_(\d+?)_.*/$1s_$2.log/; print "mv -v $d $_\n";' | bash

The perl script generates the command for the move. Leave off the pipe to bash to see if the command does what you want. The perl one-line reads the list of files from stdin and the matches the first word followed by an underscore followed by a group of digits and then prints the move command. If you need it for something other than linux, perl can simply rename the file for you. Caveats. The one-liner is raw and won't handle filenames with a path.

DannyK
  • 162