0

I am looking to change a batch of filenames to remove a letter, like so:

Stain-A_1P.fastq  to Strain-A_1.fastq
Strain-A_2P.fastq  to  Strain-A_2.fastq

I have tried the following:

rename 's/P//' *fastq
for file in *; do mv "$file" `echo $file | tr 'P' ''` ; done
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
AudileF
  • 185
  • 3
  • 11

2 Answers2

1

With bash or any other POSIX shell:

for f in *.fastq; do ext="${f##*.}"; echo mv -- "$f" "${f%?.*}.${ext}"; done
  • for f in *.fastq iterates over the .fastq files

  • ext="${f##*.}" gets (${f##*.}) and saves the extension of the file as variable ext

  • ${f%?.*} gets the portion upto the character that follows one character before last .

  • mv "$f" "${f%?.*}.${ext}" does the renaming operation, with appending the extension with the cropped prefix

This is a dry-run; drop echo for actual action:

for f in *.fastq; do ext="${f##*.}"; mv -- "$f" "${f%?.*}.${ext}"; done

If you have rename (prename):

rename -n 's{^(./.*).(\..*)}{$1$2}s' ./*.fastq
  • We are leveraging greedy match with .* to match the portion upto last .

  • The first captured group contains the portion upto the second last character before .

  • The second captured group contains the portion after the last . (including the .)

Drop -n for actual action:

rename 's{^(./.*).(\..*)}{$1$2}s' ./*.fastq

Example:

% ls -1d -- *.fastq
Stain-A_1P.fastq
Strain-A_2P.fastq

% for f in *.fastq; do ext="${f##*.}"; echo mv -- "$f" "${f%?.*}.${ext}"; done 
mv -- Stain-A_1P.fastq Stain-A_1.fastq
mv -- Strain-A_2P.fastq Strain-A_2.fastq

% rename -n 's{^(./.*).(\..*)}{$1$2}s' ./*.fastq
rename(./Stain-A_1P.fastq, ./Stain-A_1.fastq)
rename(./Strain-A_2P.fastq, ./Strain-A_2.fastq)
heemayl
  • 56,300
0

Use rename command:

for f in *.fastq; do rename 's/P\./\./' "$f" ; done

  • 's/P\./\./ - perl substitution expression: removes P followed by . (before file extension)