0

I just started to bash and I have been stuck for sometime on a simple if;then statement. I use bash to run QIIME commands which are written in python. These commands allow me to deal with microbial DNA. From the raw dataset from the sequencing I first have to first check if they match the format that QIIME can deal with before I can proceed to the rest of the commands.

module load QIIME/1.9.1-foss-2016a-Python-2.7.11
echo 'checking mapping file and demultiplexing'
validate_mapping_file.py -m $PWD/map.tsv -o $PWD/mapcheck > tmp.txt
n_words=`wc -w tmp.txt`
echo "n_words:"$n_words
if [ n_words = '9 temp.txt' ];then
split_libraries_fastq.py -i $PWD/forward_reads.fastq.gz -b $PWD/barcodes.fastq.gz -m $PWD/map.tsv -o $PWD/demultiplexed
else
  echo 'Error(s) in map'
  exit 1
fi

If the map is good I expect the following output (9 words):

No errors or warnings were found in mapping file. 

If it is bad (16 words):

Errors and/or warnings detected in mapping file.  Please check the log and html file for details.

I want to used this output to condition the following commands split_libraries_fastq.py.

I tried many different version of the if;then statement, asked help around but nothing seems to be working. Anyone of you had an idea of why the 'then' command is not ran? Also I run it through a cluster.

Here is the output when my map is good, the second command is not ran:

checking mapping file and demultiplexing
n_words:9 tmp.txt
Error(s) in map

Thanks

  • There are multiple problems in this script, but to actually *make* it work, make sure you consistently use one of `tmp.txt` or `temp.txt` and change if statement to: `if [ "$n_words" = '9 temp.txt' ]; then ...` – arco444 Oct 24 '17 at 09:36
  • Before asking a bash related question, your first reflex should be to use [shellcheck](https://www.shellcheck.net/) (as indicated in the bash tag wiki). Doing so would have shown : `if [ n_words = '9 temp.txt' ] : This expression is constant. Did you forget the $ on a variable? `. Note that it also gives some more advices regarding your code (such as the use of ` or correct quotation) – Aserre Oct 24 '17 at 10:01

2 Answers2

0

I think the code can be improved. What's wrong in your code is mostly the dollar operator used to call variables once you set them.

You are counting the rows inside temp.txt. A better version would be:

n_words=$(wc -l temp.txt)
if [ "$n_words" -eq 9 ]; then
  echo "${n_words} equal to 9"
else
  echo "${n_words} is not equal to 9"
fi
aPugLife
  • 989
  • 2
  • 14
  • 25
  • why downvoting? – aPugLife Oct 24 '17 at 09:36
  • Actually, `=` is standard for comparisons inside `[ ]`. bash allows `==` as a synonym, but it won't work in most other shells. The real problems are the lack of `$` to expand the variable (which you have), and double-quotes to prevent word splitting (which you don't have). – Gordon Davisson Oct 24 '17 at 15:14
  • @GordonDavisson Correct about the = though not an error what I wrote and anyway, I did not say it is wrong. And wrong about double quotes, as I updated my answer with EDIT 2 which is the best code version to use for this case. – aPugLife Oct 24 '17 at 15:57
0

Review shell syntax, in particular double quotes and parameter expansion. You need a dollar to expand n_words and double quotes to make it a single string notwithstanding the embedded space. For example:

if [ "$n_words" = '9 temp.txt' ]; then
    echo "good"
else
    echo "bad"
fi

Alternatively, consider omitting the file name and doing an integer comparison:

n_words=`wc -w < tmp.txt`
echo "n_words: $n_words"
if [ "$n_words" -eq 9 ]; then
#...

Finally, let me warn you that counting the number of words is a bad hack, as innocent changes in the Python script may break you shell script. I'm not familiar with Qiime, but they should provide a meaningful exit status. Try:

validate_mapping_file.py -m $PWD/map.tsv -o $PWD/mapcheck > /dev/null
exit_status=$?
echo "exit status: $exit_status"
Ale
  • 887
  • 10
  • 14
  • Thank you, the problem was indeed coming from the n_words and it now works. However the exit_status does not work and I believe this is because whether the map is good or not the command does not fail, the command is always successful: so no 1 or 0 status. – Anaïs Larue Oct 24 '17 at 11:30
  • Are you kidding? it is exactly my answer, answered after mine. Seriously? – aPugLife Oct 24 '17 at 15:59
  • @Nihvel Sorry, I saw your answer after posting mine – Ale Oct 25 '17 at 11:50