0

I need some help. I want to rename very many files with unique filenames using bash. I want to keep part of the original filename.

For example:

current file name new file name
F1.R23.fastq.gz 10_1.F1.R23.fastq.gz
F2.R7.fastq.gz empty_3_1.F2.R7.fastq.gz
F32.R3.fastq.gz 63_3.F32.R3.fastq.gz
F5.R7.fastq.gz Blank_3.F5.R7.fastq.gz
F2.R2.fastq.gz N5_1.F2.R2.fastq.gz

What I have, is a file containing a column with the original names, and a column containing what I want to add to the names. Like so:

file sample
F1.R23.fastq.gz 10_1
F2.R7.fastq.gz empty_3_1
F32.R3.fastq.gz 63_3
F5.R7.fastq.gz Blank_3
F2.R2.fastq.gz N5_1

I would really appreciate if anybody has a way of doing this. I have potentially thousands of files to rename, some with complicated names and in a random order, and so it’s not really feasible to do this by hand.

Thank you!

1 Answer 1

0

First, create a csv file called files-to-rename.csv, or convert the spreadsheet you have to CSV format. The contents of the file should be like this:

F1.R23.fastq.gz,10_1
F2.R7.fastq.gz,empty_3_1
F32.R3.fastq.gz,63_3
F5.R7.fastq.gz,Blank_3
F2.R2.fastq.gz,N5_1

Then run this command, making sure you are in the same directory as the files:

while IFS=$',\r' read -r source dest ; do
  mv -v "$source" "${dest}.${source}"
done < files-to-rename.csv

The above will not work if the csv file has DOS line endings. You can use the dos2unix files-to-rename.csv command to make sure the file is in UNIX line endings.


Otherwise, use this safer snippet below:

while read line; do
  source=$(echo $line | cut -d, -f1)
  dest=$(echo $line | cut -d, -f2)

  mv -v "$source" "${dest}.${source}"
done < files-to-rename.csv

4
  • 1
    I'd adapt the mv command to attempt the rename only if the source existed and the destination did not - [ -f "$source" ] && [ ! -f "$dest.$source" ] && mv "$source" "$dest.$source". The first time through I'd also suggest amending mv to echo mv so the OP can see what's going on without actually changing any of the file names Commented Dec 15, 2021 at 12:44
  • 1
    Consider using while IFS=$',\r' read -r source dest junk. Not only is it cleaner to split directly at a comma, but it will also handle an unexpected trailing CR (allowing for the possibility that the CSV was converted from the spreadsheet on a Windows system) Commented Dec 15, 2021 at 12:45
  • @roaima Thanks. Updated the answer. However, your solution will end up having weird chars in the renamed file if the csv file has DOS line endings.
    – GMaster
    Commented Dec 15, 2021 at 14:11
  • @GMaster, in Bash that seems to work for a single trailing CR, but not for two. It doesn't work in zsh though. IFS=$',\r' read -r a b x and ignoring x seems like it might work better. Or maybe it's better to just pipe the input through tr -d '\r'.
    – ilkkachu
    Commented Dec 15, 2021 at 15:20

You must log in to answer this question.

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