Bash to remove find and remove specific extension

The bash below executes and does find all the .bam files in each R_2019 folder. However set -x shows that the .bam extension only gets removed from one .bam file in each folder (appears to be the last in each). Why is it not removing the extension from each (this is $SAMPLE )? Thank you :).

set -x
DIR=/home/cmccabe/Desktop/f1   ## define data directory path
for RDIR in "$DIR"/R_2019* ; do
      BAM=$(find "$RDIR"/bam -type f -name "*.bam" -printf '%P\n')
       SAMPLE=$(echo $BAM|cut -d. -f1)
echo "$SAMPLE"
done
R_2019_03_12_11_10_20_user_S5-0271-99
     -bam
       19-0000-LastName-FirstName.bam.bai 19-0000-LastName-FirstName.bam 19-0001-Las-Fir.bam.bai 19-0001-Las-Fir.bam 190319-Control.bam.bai 190319-Control.bam
R_2019_03_12_13_59_54_user_S5-0271-100
     -bam
        19-0004-La-Fi.bam.bai 19-0004-La-Fi.bam.bam 19-0005-Last-Firs.bam.bai 19-0005-Last-Firs.bam 19-0008-LastN-FirstN.bam.bai 19-0008-LastN-FirstN.bam 190320-Control.bam.bai 190320-Control.bam

set -x

set -x
cmccabe@DTV-A5211QLM:~$ DIR=/home/cmccabe/Desktop/f1   ## define data directory path
+ DIR=/home/cmccabe/Desktop/f1
cmccabe@DTV-A5211QLM:~$ for RDIR in "$DIR"/R_2019* ; do
>       BAM=$(find "$RDIR"/bam -type f -name "*.bam" -printf '%P\n')
>        SAMPLE=$(echo $BAM|cut -d. -f1)
> echo "$SAMPLE"
> done
+ for RDIR in '"$DIR"/R_2019*'
++ find /home/cmccabe/Desktop/f1/R_2019_03_12_11_10_20_user_S5-0271-99/bam -type f -name '*.bam' -printf '%P\n'
+ BAM='190319-Control.bam
19-0001-Las-Fir.bam
19-0000-LastName-FirstName.bam'
++ echo 190319-Control.bam 19-0001-Las-Fir.bam 19-0000-LastName-FirstName.bam
++ cut -d. -f1
+ SAMPLE=190319-Control
+ echo 190319-Control
190319-Control
+ for RDIR in '"$DIR"/R_2019*'
++ find /home/cmccabe/Desktop/f1/R_2019_03_12_13_59_54_user_S5-0271-100/bam -type f -name '*.bam' -printf '%P\n'
+ BAM='190320-Control.bam
19-0008-LastN-FirstN.bam
19-0005-Last-Firs.bam
19-0004-La-Fi.bam'
++ echo 190320-Control.bam 19-0008-LastN-FirstN.bam 19-0005-Last-Firs.bam 19-0004-La-Fi.bam
++ cut -d. -f1
+ SAMPLE=190320-Control
+ echo 190320-Control
190320-Control

You need an inner loop

# -------------- new inner loop
     find "$RDIR"/bam -type f -name "*.bam" -printf '%P\n' |
    while read BAM
    do
       SAMPLE=$(echo $BAM|cut -d. -f1)  #  lose the cut and use this instead: SAMPLE=${BAM%%.*}  
      #   Try it first before running in a script
      # do things with $SAMPLE here  I guess:  like mv $BAM $SAMPLE
   done
# ---------- end new inner loop

Try not use use a lot of child processes when bash does the same thing as a builtin. :slight_smile:

Your code did this: put all filenames into variable BAM, zap just one. You need to read and then zap each file inside some type of loop.
I need to learn how to type and fix errors on the fly. I had to edit this post three times :frowning:

1 Like

Thank you very much for your help and explanations :slight_smile:

I think you could spare yourself a lot of hassle (and the system a lot of work) doing it like this:

for RDIR in "$DIR"/R_2019* ; do
     find "$RDIR"/bam -type f -name "*.bam" -exec /path/to/movescript.sh {} \;
done

where /path/to/movescript.sh would contain

!# /bin/sh

echo mv "${1}" "${1%.bam}"

exit $?

If you are satisfied with the list of commands remove the "echo" in the script.

I hope this helps.

bakunin

1 Like

Thank you very much, very helpful :).