Renaming multiples files with a bash loop

Geparada picture Geparada · Jan 17, 2012 · Viewed 50k times · Source

I need to rename 45 files, and I don't want to do it one by one. These are the file names:

chr10.fasta         chr13_random.fasta  chr17.fasta         chr1.fasta          chr22_random.fasta  chr4_random.fasta  chr7_random.fasta  chrX.fasta
chr10_random.fasta  chr14.fasta         chr17_random.fasta  chr1_random.fasta   chr2.fasta          chr5.fasta         chr8.fasta         chrX_random.fasta
chr11.fasta         chr15.fasta         chr18.fasta         chr20.fasta         chr2_random.fasta   chr5_random.fasta  chr8_random.fasta  chrY.fasta
chr11_random.fasta  chr15_random.fasta  chr18_random.fasta  chr21.fasta         chr3.fasta          chr6.fasta         chr9.fasta         
chr12.fasta         chr16.fasta         chr19.fasta         chr21_random.fasta  chr3_random.fasta   chr6_random.fasta  chr9_random.fasta
chr13.fasta         chr16_random.fasta  chr19_random.fasta  chr22.fasta         chr4.fasta          chr7.fasta         chrM.fasta

I need to change the extension ".fasta" to ".fa". I'm trying to write a bash script to do it:

for i in $(ls chr*)

do

NEWNAME = `echo $i | sed 's/sta//g'`

mv $i $NEWNAME

done

But it doesn't work. Can you tell me why, or give another quick solution?

Thanks!

Answer

Benoit picture Benoit · Jan 17, 2012

Several mistakes here:

  • NEWNAME = should be without space. Here bash is looking for a command named NEWNAME and that fails.
  • you parse the output of ls. this is bad if you had files with spaces. Bash can build itself a list of files with the glob operator *.
  • You don't escape "$i" and "$NEWNAME". If any of them contains a space it makes two arguments for mv.
  • If a file name begins with a dash mv will believe it is a switch. Use -- to stop argument processing.

Try:

for i in chr*
do
  mv -- "$i" "${i/%.fasta/.fa}"
done

or

for i in chr*
do
  NEWNAME="${i/%.fasta/.fa}"
  mv -- "$i" "$NEWNAME"
done

The "%{var/%pat/replacement}" looks for pat only at the end of the variable and replaces it with replacement.