2

I am trying to download a bunch of files and rename them as I go. the download portion works correctly, but i can't get it to rename the files. This is the script I'm using:

COUNTER=0
for (( i = 696; i <= 773; i++ ))
  do
  fastq-dump --split-3 --accession SRR546$i
mv SRR546"$i"_1 ./"$COUNTER"mVD_SRR546$i_1
mv SRR546"$i"_2 ./"$COUNTER"mVD_SRR546$i_2
gzip *.fastq

COUNTER=$[COUNTER + 1]
done

This will correctly download the file SRR546696, SRR546697 etc. but does nothing to rename them.

I also tried using:

rename 's/SRR/"$COUNTER"mVD_SRR/' *.fastq

but this also did nothing.

codeforester
  • 28,846
  • 11
  • 78
  • 104
Greg T.D.
  • 49
  • 5

2 Answers2

5

You need to double quote the arguments to prevent word splitting and globbing. At the same time, you need to preserve the variable names with {}:

counter=0
for ((i = 696; i <= 773; i++)); do
  fastq-dump --split-3 --accession "SRR546$i"
  mv "SRR546${i}_1" "./${counter}mVD_SRR546${i}_1"
  mv "SRR546${i}_2" "./${counter}mVD_SRR546${i}_2"
  gzip *.fastq
  ((counter++))
done

Instead of hardcoding "SRR546" in so many places, you could use a variable to hold that string and make your code more readable:

counter=0 srr="SRR546"
for ((i = 696; i <= 773; i++)); do
  fastq-dump --split-3 --accession "$srr$i"
  mv "$srr${i}_1" "./${counter}mVD_${srr}${i}_1"
  mv "$srr${i}_2" "./${counter}mVD_${srr}${i}_2"
  gzip *.fastq
  ((counter++))
done

Improvements:

  • use lower case for your normal variables (counter instead of COUNTER)
  • use quoting to prevent word splitting and globbing (though not an issue in your problem since the variable holds a number, free from space or other meta characters
  • use a single set of double quotes rather than multiple single quotes
  • use ++ operator to increment counter as in ((counter++) and ((...)) is a better syntax than $[ ... ]

You may want to add error checking to your code.

Related

codeforester
  • 28,846
  • 11
  • 78
  • 104
  • 1
    Good answer, the `${parameter}` is required `"...when parameter is followed by a character which is not to be interpreted as part of its name."` (man bash - Parameter Expansion) – David C. Rankin Feb 12 '19 at 02:20
  • @codeforester : I was surprised that `$[ .... ]` is also legal for arithmetic evaluation. I could verify that it **does** work, but I didn't find this syntax mentioned in the bash man page (looked in _Arithmetic Expansion_ and _ARITHMETIC EVALUATION_). Is this a "hidden feature" of bash? – user1934428 Feb 12 '19 at 07:18
  • @user1934428 See [Obsolete and deprecated syntax](https://wiki.bash-hackers.org/scripting/obsolete). – codeforester Feb 12 '19 at 17:14
  • 1
    @codeforester : Interesting! I had only looked in the man-page, and there (version 4.4.12 built for Cygwin), there is no chapter about deprecation (I searched case-insensitively for _obsolete_ and _deprecate_). Thank you for providing the link! – user1934428 Feb 13 '19 at 08:17
0

When you combine a variable name with a string, only string should be quoted:

COUNTER=0
for (( i = 696; i <= 773; i++ )); do

    fastq-dump --split-3 --accession 'SRR546'$i

    mv 'SRR546'$i'_1' ./$COUNTER'mVD_SRR546'$i'_1'
    mv 'SRR546'$i'_2' ./$COUNTER'mVD_SRR546'$i'_2'
    gzip *.fastq

    COUNTER=$[COUNTER + 1]
done
  • 1
    No, that's not really true. There's nothing in (say) the string `mVD_SRR546` that demands quoting, all the characters there are just normal characters that have no special meaning to the shell. You would want to quote strings that have special characters, though, if you don't want the special meanings (e.g. `()*?$` etc. plus all whitespace). As for the variables, those you _should_ double-quote most of the time, mainly to avoid [word splitting](https://mywiki.wooledge.org/WordSplitting) in case they contain whitespace. – ilkkachu Feb 13 '19 at 00:02
  • See also: [When is double-quoting necessary?](https://unix.stackexchange.com/questions/68694/when-is-double-quoting-necessary) on unix.SE – ilkkachu Feb 13 '19 at 00:03