0

I have pipeline like that:

pipeline | test $number -eq 3 && while read A B C D; do...; done 

But that doesn't work because while read can't read arguments from pipeline anymore bec of test $number -eq 3 &&

How can I solve that? I musn't use awk or sed.

Marta Koprivnik
  • 385
  • 2
  • 3
  • 10

3 Answers3

2

You can use a process substitution:

test $number -eq 3 && while read A B C D;
do
    ...
done < <(pipeline)

For example:

$ n=3
$ test $n -eq 3 && while read A B C; do echo "A: $A, B: $B, rest: $C --"; done < <(echo a b c d e f)
A: a, B: b, rest: c d e f --
Community
  • 1
  • 1
fedorqui
  • 275,237
  • 103
  • 548
  • 598
1

It seems to me like the clearest way to write your code would be to use an if:

if test $number -eq 3; then
    pipeline | while read A B C D; do...; done
fi

If you really want to use &&, then I guess you can use this:

test $number -eq 3 && pipeline | while read A B C D; do...; done

...but personally I don't think it's as clear.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • 1
    I would tend to agree, unless the `do...` in the example changes the value of `$number`, in which case the conditional would be wrong anyway. – Michael Vehrs May 03 '16 at 11:40
0

I'll use seq 20 | paste - - - - as your "pipeline" to generate some lines with 4 words per line.

Here's your problem:

$ seq 20 | paste - - - - | test $number -eq 3 && while read A B C D; do echo "A=$A B=$B C=$C D=$D"; done
^C

The while loop is stuck waiting for input on stdin.

This fix just groups the test and loop together, so read can access the pipeline's output:

$ seq 20 | paste - - - - | { test $number -eq 3 && while read A B C D; do echo "A=$A B=$B C=$C D=$D"; done; }
A=1 B=2 C=3 D=4
A=5 B=6 C=7 D=8
A=9 B=10 C=11 D=12
A=13 B=14 C=15 D=16
A=17 B=18 C=19 D=20
glenn jackman
  • 238,783
  • 38
  • 220
  • 352