jnmf
jnmf

Reputation: 137

Why isn't this code getting the name of the file?

In a folder containing many files like this:

filtered_bcbc8273.bam
filtered_a8626340.bam
filtered_fae86ca5.bam

I want to use samtools (it adds .bam in the end) to sort them and save the sorted file as:

sorted_bcbc8273.bam
sorted_a8626340.bam
sorted_fae86ca5.bam

but my output is:

sorted_.bam

what's wrong here?

cd /work/folder/
for l in *; do
name=$(echo "$l" | cut -d "_" -f 2 | cut -d "." -f 1)
samtools sort -n /work/folder/filtered_$name\.bam /work/folder/sorted/sorted_$name\
cd ..
done

Upvotes: 0

Views: 43

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295736

To make its behavior a bit more reliable, I'd suggest rewriting this like so:

cd /work/folder
for f in filtered_*.bam; do
  [[ -e $f ]] || continue  # skip any file that doesn't exist (ie. glob failed)
  id=${f#filtered_}                  # strip prefix from filename
  id=${id%.bam}                      # strip suffix from filename
  samtools sort -n "$f" "sorted_$id" # run tool
done

Advantages:

  • Using the more specific glob expression (filtered_*.bam) ensures that names meet our expectations, and thus that we aren't failing due to iterating over files that don't match our expected pattern.
  • Using parameter expansions for trimming known prefixes and suffixes prevents the cut operations from removing anything other than those known prefixes or suffixes, thus behaving more reliably.
  • Using the shell's built-in string manipulation is faster than forking a subshell to launch an external tool (when doing so within an inner loop; an external tool can be more efficient when structured to be run only once for an entire stream of inputs).

Finally, having the cd .. within the loop ensured that until your working directory reached the root, each loop iteration would be run in a different directory.

See BashFAQ #100 for more detail on bash's string-manipulation primitives in general, or the bash-hackers parameter expansion page for a focused explanation of the primitives used and others akin to them.

Upvotes: 3

Related Questions