Find the answer to your Linux question:
Results 1 to 4 of 4
Hi I'm trying to write a shell script, which calls an eternal command, that outputs multiple lines. I can capture the output with VAR=$(foobar) (where foobar is the external command), ...
  1. #1
    Just Joined!
    Join Date
    Oct 2007
    Posts
    9

    newlines stripped from captured output

    Hi

    I'm trying to write a shell script, which calls an eternal command, that outputs multiple lines. I can capture the output with VAR=$(foobar) (where foobar is the external command), but all the lines are concatenated into a single line. Is there any way to capture newlines as well?
    Alternatively, is there a way to pipe the output of one command into stdin of multiple commands?

  2. #2
    Linux User
    Join Date
    Aug 2006
    Posts
    458
    how does $VAR look like now? and what do you expect it to appear as?

  3. #3
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    troelskn wishes to pipe the output from one program to each of two or more other programs, while running the original input program only once.

    Let's call the original program fred.sh:
    Code:
    #!/bin/bash
    
    for ((jndex=0; jndex<10; jndex++))
    {
      echo "x$jndex  y$jndex"   # notice the two spaces before the y
    }
    The output from that program is this:
    Code:
    x0  y0
    x1  y1
    x2  y2
    x3  y3
    x4  y4
    x5  y5
    x6  y6
    x7  y7
    x8  y8
    x9  y9
    troelskn wishes to feed those ten lines to each of two other programs. Let's use rev as one of these programs; if we do this
    Code:
    fred.sh | rev
    we get
    Code:
    0y  0x
    1y  1x
    2y  2x
    3y  3x
    4y  4x
    5y  5x
    6y  6x
    7y  7x
    8y  8x
    9y  9x
    Let's use grep -n ^ as the other program; if we do this
    Code:
    fred.sh | grep -n ^
    we get
    Code:
    1:x0  y0
    2:x1  y1
    3:x2  y2
    4:x3  y3
    5:x4  y4
    6:x5  y5
    7:x6  y6
    8:x7  y7
    9:x8  y8
    10:x9  y9
    But we can't just do
    Code:
    fred.sh | rev
    fred.sh | grep -n ^
    because troelskn wants to run the input program only once. troelskn tried the following, I'm sure, because that's what would have triggered his question:
    Code:
    #!/bin/bash
    
    var=$(fred.sh)
    
    echo === begin variable
    echo $var
    echo === end variable
    
    echo piping through rev:
    echo $var | rev
    echo piping through grep -n ^:
    echo $var | grep -n ^
    troelskn's problem is that all the data from fred.sh would be gathered on one line. The output from this program is:
    Code:
    === begin variable
    x0 y0 x1 y1 x2 y2 x3 y3 x4 y4 x5 y5 x6 y6 x7 y7 x8 y8 x9 y9
    === end variable
    piping through rev:
    9y 9x 8y 8x 7y 7x 6y 6x 5y 5x 4y 4x 3y 3x 2y 2x 1y 1x 0y 0x
    piping through grep -n ^:
    1:x0 y0 x1 y1 x2 y2 x3 y3 x4 y4 x5 y5 x6 y6 x7 y7 x8 y8 x9 y9
    There are two obvious solutions to this problem. One is if you're fairly sure that you can fit all the data into memory at the same time, as would be the case here. Then you can do this:
    Code:
    #!/bin/bash
    
    fred.sh | {
      while read
      do
        array[${#array[@]}]=$REPLY
      done
    
      echo === begin array
      for ((xxx=0; xxx<${#array[@]}; xxx++))
      do
        echo "${array[$xxx]}"
      done
      echo === end array
    
      for ((xxx=0; xxx<${#array[@]}; xxx++))
      do
        echo "${array[$xxx]}"
      done | rev
    
      for ((xxx=0; xxx<${#array[@]}; xxx++))
      do
        echo "${array[$xxx]}"
      done | grep -n ^
    }
    But if there is much data, you can always punt and put it in a scratch file:
    Code:
    #!/bin/bash
    
    fred.sh > scratchfile
    
    echo === begin array
    cat scratchfile
    echo === end array
    
    rev < scratchfile
    
    grep -n ^ < scratchfile
    
    rm scratchfile
    In either case, the output is:
    Code:
    === begin array
    x0  y0
    x1  y1
    x2  y2
    x3  y3
    x4  y4
    x5  y5
    x6  y6
    x7  y7
    x8  y8
    x9  y9
    === end array
    0y  0x
    1y  1x
    2y  2x
    3y  3x
    4y  4x
    5y  5x
    6y  6x
    7y  7x
    8y  8x
    9y  9x
    1:x0  y0
    2:x1  y1
    3:x2  y2
    4:x3  y3
    5:x4  y4
    6:x5  y5
    7:x6  y6
    8:x7  y7
    9:x8  y8
    10:x9  y9
    Hope this helps.

  4. #4
    Just Joined!
    Join Date
    Oct 2007
    Posts
    9
    Quote Originally Posted by wje_lf View Post
    troelskn wishes to pipe the output from one program to each of two or more other programs, while running the original input program only once.
    Exactly.

    Quote Originally Posted by wje_lf View Post
    Hope this helps.
    Very much. Thanks for the detailed reply.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...