Bash to add portion of text to files in directory using numerical match

In the below bash I am trying to rename eachof the 3 text files in /home/cmccabe/Desktop/percent by matching the numerical portion of each file to lines 3,4, or 5 in /home/cmccabe/Desktop/analysis.txt . There will always be a match between the files. When a match is found each text file in /home/cmccabe/Desktop/percent is renamed adding the textafter the _ (underscore) in /home/cmccabe/Desktop/analysis.txt to each line.

text file in /home/cmccabe/Desktop/percent - there could be a maximum of 3 files in this directory

00-0000_fbn1_20xcoverage.txt
01-0101_fbn1_20xcoverage.txt
02-0202_fbn1_20xcoverage.txt

text file in /home/cmccabe/QC/analysis.txt

  status: complete 
id names:  
00-0000_Last-First 
01-0101_LastN-FirstN
02-0202_La-Fi  

desired result in /home/cmccabe/QC/percent

  00-0000_Last-First_fbn1_20xcoverage.txt
01-0101_LastN-FirstN_fbn1_20xcoverage.txt
02-0202_La-Fi_fbn1_20xcoverage.txt

The set -x shows that the files are renamed correctly but they are not moved to /home/cmccabe/Desktop/percent . Currently the 3 text files in there are the same as above (without the name added to them).

set -x

+ IFS=_
+ read -r id newname
++ tail -n+3 /home/cmccabe/QC/analysis
++ find . -name '00-0000*.txt' -printf %f
+ oldfilename=00-0000_fbn1.txt
+ '[' -n 00-0000_fbn1.txt ']'
+ echo mv '"00-0000_fbn1.txt"' '"00-0000_Last-First_fbn1.txt"'
mv "00-0000_fbn1.txt" "00-0000_Last-First_fbn1.txt"
+ IFS=_
+ read -r id newname
++ find . -name '01-0101*.txt' -printf %f
+ oldfilename=01-0101_fbn1.txt
+ '[' -n 01-0101_fbn1.txt ']'
+ echo mv '"01-0101_fbn1.txt"' '"01-0101_LastN-FirstN_fbn1.txt"'
mv "01-0101_fbn1.txt" "01-0101_LastN-FirstN_fbn1.txt"
+ IFS=_
+ read -r id newname
++ find . -name '02-0202*.txt' -printf %f
+ oldfilename=02-0202_fbn1.txt
+ '[' -n 02-0202_fbn1.txt ']'
+ echo mv '"02-0202_fbn1.txt"' '"02-0202_La-Fi_fbn1.txt"'
mv "02-0202_fbn1.txt" "02-0202_La-Fi_fbn1.txt"
+ IFS=_
+ read -r id newname

Description of what I think is going on (I will try to include these:

read the analysis.txt file split each line (i.e 00-0000_Last-First) to two fields using _ as delimiter:
id=00-000
newname=Last-First

Then using this file id read from file analysis.txt check (using find) to see if a file exists starting with the same id.
The matching filename is returned in variable $oldfilename .
If this variable is not empty mv the files.
tail -n+3 is used to ignore the first two lines of the analysis.txt
[/CODE]bash

while IFS="_" read -r id newname;do
#echo "id=$newid - newname=$newname"  #for cross check 
oldfilename=$(find . -name "${id}*.txt" -printf %f)
[ -n "$oldfilename" ] && echo mv \"$oldfilename\" \"${id}_${newname}_${oldfilename#*_}\";
done < <(tail -n+3 /home/cmccabe/QC/analysis.txt)

I am not sure why the mv is working and the 3 text files remain the same. The echo shows them renamed correctly. Thank you :).

Take a look at your code again. There is no mv command in your code; only an echo command. If the echo shows that your script is correctly determining what arguments should be passed to mv , what happens if you change the line:

[ -n "$oldfilename" ] && echo mv \"$oldfilename\" \"${id}_${newname}_${oldfilename#*_}\";

in your code to:

[ -n "$oldfilename" ] && mv "$oldfilename" "${id}_${newname}_${oldfilename#*_}";

(i.e., remove the echo and the backslashes)?

1 Like

That fixed it, but now I have the same problem I did before. The bash, as is works great as long as all 3 files are in the directory /home/cmccabe/QC/percent .

Since I run a process on each file, after it gets renamed it is moved to the directory. When the next filename gets renamed, the other one gets duplicated. If there is a third the first filename repeats 3 times the second filename duplicated and third is fine.

So if in /home/cmccabe/QC/percent

00-0000_Last-First_fbn1.txt

code executes a second time:

00-0000_Last-First_Last-First_fbn1.txt  ---- file already in dir
01-0101_LastN-FirstN_fbn1.txt

code executes a third time:

00-0000_Last-First_Last-First_Last-First_fbn1.txt  ---- file already in dir
01-0101_LastN-FirstN_LastN-FirstNfbn1.txt   --- this is the 2nd file in dir
02-0202_La-Fi_fbn1.txt

Maybe I just need to only execute the command once after all 3 files are in the directory? If a file is in the directory already it has been renamed already but I'm not sure how to prevent the duplication. Thank you :).