2

I'm trying to put the amount of lines in a gzipped file in a variable, later on I plan to use this stdout for another process using tee. Why won't the value of wc -l get put into the variable and how can I fix this?

[]$ gzip -dc BC102.fastq.gz | wc -l
4255588
[]$ gzip -dc BC102.fastq.gz | echo $(wc -l)
4255588
[]$ gzip -dc BC102.fastq.gz | reads=$(wc -l); echo $reads
0

The whole line is eventually supposed to look like

gzip -dc BC102.fastq.gz | tee >(reads=$(wc -l)) | cutadapt -ga...

I don't see how this is a duplicate from How to set a variable to the output from a command in Bash? since I was already applying the answer listed there to echo the value of wc -l directly, but it won't be inserted into the variable.

Community
  • 1
  • 1
Xizam
  • 699
  • 7
  • 21
  • @hek2mlg This is not a duplicate because the output shall be used *twice*. –  May 24 '16 at 12:10
  • 1
    @LutzHorn Of course it is a duplicate. Btw, I consider the question "What is the result of `1+2`" as a duplicate of the question "What is the result of `1+1`". – hek2mgl May 24 '16 at 12:14
  • The question you think this is a duplicate of is only about capturing stdout in a variable. This question is about capturing the output *plus* using it in another pipe. –  May 24 '16 at 12:15
  • 1
    This is more like a duplicate, but I think there are better ones: http://stackoverflow.com/questions/6441868/how-do-i-read-standard-out-into-a-bash-variable-without-using-a-subshell-or-a-na – rici May 24 '16 at 14:21

2 Answers2

3

tee writes to stdout plus to all files given as arguments. It does not write to two different pipes you could attach to.

Try this:

t=$(tempfile)
reads=$(gzip -dc BC102.fastq.gz | tee $t | wc -l)

Now you can continue in your script

cutadapt -ga $t

while reads contains the number of lines.

  • Since I want to use `gzip -dc BC102.fastq.gz | tee >(reads=$(wc -l)) | cutadapt -ga...` I dont think I can use that. – Xizam May 24 '16 at 11:51
  • Ah, I clearly misunderstood the use of tee. Perfect, thanks! – Xizam May 24 '16 at 12:13
2

If you set a variable in a subshell, it will have no effect on the parent. That is what happens with

gzip -dc BC102.fastq.gz | tee >(reads=$(wc -l)) | cutadapt -ga...

But nothing obvious stops you from continuing the pipe in the subshell:

reads=$(wc -l <(gzip -dc BC102.fastq.gz | tee >(cutadapt -ga... )))
rici
  • 234,347
  • 28
  • 237
  • 341