Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

edit file names using separate txt file information in R or bash

Tags:

r

I have a txt file with CHEM_ID and COMP_ID columns. These looks like:

CHEM_ID     COMP_ID
M35         metmss_42370
M50         metmss_485
M55         metmss_27665

Separately to this txt file, I have hundreds of files which I want to amend the file names of, using this txt file information. Currently, these files have the following names:

BIB.metmss_42370.european-2024-03-04.txt.gz

And so on, where each 'metmss_xxxx' number is different.

Can I edit these file names, [in bash or R], so that

  1. they also include the corresponding CHEM_ID [as specified in the txt file above]
  2. 'metmss' is replaced with 'C'.

e.g. where CHEM_ID is M35 - the one which corresponds to metmss_42370

BIB.M35.C42370.european-2024-03-04.txt.gz

?

I have not tried any solutions yet, as I have no idea where to start and I'm afraid to do anything which destroys the files I have in any way.

like image 413
ayeepi Avatar asked Oct 29 '25 10:10

ayeepi


2 Answers

setwd where the files live, then you can do

> fnm <- list.files(pattern='^BIB', full.names=TRUE)
> ids <- read.table('foo.txt', header=TRUE)  ## file w/ ID columns
> lapply(seq_len(nrow(ids)), \(i) {
+   old <- fnm[grep(ids$COMP_ID[i], fnm)]
+   new <- sub('metmss_', sprintf('%s.C', ids$CHEM_ID[i]), old)
+   file.rename(old, new)
+ })

Please make backup beforehand, there's no undo.

like image 193
jay.sf Avatar answered Oct 31 '25 23:10

jay.sf


Here is a bash solution

#!/bin/bash

if   test "$1" = "check"
then GUARDIAN="echo"
elif test "$1" = "doit"
then GUARDIAN=
else echo "Please run this as 'renamer check' to printout what would happen, or 'renamer doit' to actually do it." && exit 1
fi

cat legend.txt | while read -r CHEM_ID COMP_ID
do
     if test "${CHEM_ID}" = "CHEM_ID";   then continue;   fi

     if   test "$( ls "BIB.${COMP_ID}."*".txt.gz" 2>/dev/null | wc -l )" -gt 0
     then for  FILE in "BIB.${COMP_ID}."*".txt.gz"
          do   ${GUARDIAN} mv "${FILE}" "BIB.${CHEM_ID}.C${COMP_ID#metmss_}.${FILE#"BIB.${COMP_ID}."}"
          done
     else echo "Warning: did not find file for COMP_ID ${COMP_ID}."
     fi
done

The main logic is in the 'mv' line, but I made it slightly safer in case you want to test first. Run this as "renamer check" to printout what would happen, or "renamer doit" to actually rename the files.

If you want to copy instead of moving, simply change mv to cp (or if you want to copy to a directory, prepend the directory name to the second argument of the cp command). 'rename check' will help you confirm the outputs are correct before running the command.

UPDATE: addressed Saboteur's comment.

like image 29
Tasos Papastylianou Avatar answered Nov 01 '25 00:11

Tasos Papastylianou