UNIX rename with Regex to remove middle string from file names

Filenames look like this:

CMRLPCR000020_S235_M.bum
CMRLPCR000021_S238_M.bum
CMRLPCR000022_S2341_M.bum

I want to change it to :

CMRLPCR000020_M.bum
CMRLPCR000021_M.bum
CMRLPCR000022_M.bum

I tried with regex, but no success

rename 's\^(CMRLPCR)\d{6}\_(?:.{4})(\.)\^(CMRLPCR)\d{6}\_(\.)\' *.bum
 

Edited to address comments below.

Hello genehunter,

Thanks for showing your efforts in form of codes.

But your all shown output sample file names CMRLPCR000020_M.bum are same. Wouldn't it overwrite the file, since all file names are same. Lets say you have renamed 1 file with code and trying the 2nd one now, now when rename command runs it will rename 2nd file and overwrite the first file since first and second file names are same.

Kindly do elaborate your question more clearly and let us know.

Thanks,
R. Singh

Yes, sorry.. that was sloppy copy pasting.
Edited to correct it

an ex.:

ls -1 | grep ".*_.*_.*.bum" | while IFS=_ read a b c ; do mv ${a}_${b}_${c} ${a}_${c} ; done

Thank you for the mv solution.
Can you help doing this using rename function.
the version I have is rename from util-linux 2.23.2, which uses substring match.
Thanks

Hello genehunter,

This could be easily done with bash, could you please try following.
I am using parameter expansion functionality of bash here.

val="_"
for file in *.bum
do
  first_part_of_new_file="${file%%_*}"
  second_part_of_new_file="${file##*_}"
  echo "mv $file $first_part_of_new_file$val$second_part_of_new_file"
done

Above will print commands to rename the files only as follows. Once you are Happy with above's results then you coudl use actual mv command in above code and could remove echo from it.

Thanks,
R. Singh

Hi

prename -n 's/^(CMRLPCR\d{6}).*(_[^_]*)$/\1\2/' *.bum

--- Post updated at 19:35 ---

find *.bum -prune -exec bash -c 'mv $0 ${0//_*_/_}' {} \;

--- Post updated at 19:50 ---

I removed the -prune option and, to be consistent, inserted the "echo" for debug

find *.bum -exec bash -c 'echo mv $0 ${0//_*_/_}' {} \;

I think you expect rename -> prename as is the case on Debian. Another one with prename:

prename -n 's/^(CMRLPCR\d{6})_[^_]*/$1/' *.bum

Or

prename -n 's/_[^_]*//' CMRLPCR??????_*.bum

The rename from util-linux is much different, and IMHO cannot have references like $1 $2 that refer to (group1) (group2) .
The only portable solution is a loop.

1 Like