Pass the output of previous command to next as an argument

525,255

Solution 1

You are confusing two very different types of inputs.

  1. Standard input (stdin)
  2. Command line arguments

These are different, and are useful for different purposes. Some commands can take input in both ways, but they typically use them differently. Take for example the wc command:

  1. Passing input by stdin:

    ls | wc -l
    

    This will count the lines in the output of ls

  2. Passing input by command line arguments:

    wc -l $(ls)
    

    This will count lines in the list of files printed by ls

Completely different things.

To answer your question, it sounds like you want to capture the rate from the output of the first command, and then use the rate as a command line argument for the second command. Here's one way to do that:

rate=$(command1 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p')
command2 -t "rate was $rate"

Explanation of the sed:

  • The s/pattern/replacement/ command is to replace some pattern
  • The pattern means: the line must start with "rate" (^rate) followed by any two character (..), followed by 0 or more digits, followed by a %, followed by the rest of the text (.*)
  • \1 in the replacement means the content of the first expression captured within \(...\), so in this case the digits before the % sign
  • The -n flag of the sed command means to not print lines by default. The p at the end of the s/// command means to print the line if there was a replacement. In short, the command will print something only if there was a match.

Solution 2

I tend to use this:

command1 | xargs -I{} command2 {}

Pass output of command1 through xargs using substitution (the braces) to command2. If command1 is find be sure to use -print0 and add -0 to xargs for null terminated strings and xargs will call command2 for each thing found.

In your case (and taking the sed line from @Janos):

command1 -p=aaa -v=bbb -i=4 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p' | xargs -I{} command2 -t="rate was {}"

Solution 3

To simulate the output of command1 I am using this echo statement:

$ echo -e "Foo\nrate (10%) - name: value - 10Kbps\nBar"
$ alias command1='echo -e "Blah\nrate (10%) - name: value - 10Kbps\nBlag"'

A quick test:

$ command1
Blah
rate (10%) - name: value - 10Kbps
Blag

Thats all good, so lets parse it out:

$ command1 | grep 'rate'
rate (10%) - name: value - 10Kbps

So we get the line we want out of command1, lets pass that into command2:

$ alias command2='echo'
$ command2 -t="rate was "$(command1 | grep 'rate')
-t=rate was rate (10%) - name: value - 10Kbps

I'm expecting "rate was "$(command1 | grep 'rate') to concatenate automatically. If that doesn't work because of whitespace, you should be able to pass the input like so instead:

$ alias command2='echo'
$ command2 -t=$(echo '"rate was ' $(command1 | grep 'rate') '"')
-t="rate was rate (10%) - name: value - 10Kbps "

Solution 4

I generally use `command` to place it's output as argument to another command. For e.g., to find resource consumed by process foo on freebsd will be:

procstat -r `pgrep -x foo`

Here, pgrep is used to extract the PID of process foo which is passed to procstat command which expects PID of process as argument.

Solution 5

Try this using & :

command | grep -oP '\$>\s+rate\s+\(\K[^\)]+'
Share:
525,255

Related videos on Youtube

basedian
Author by

basedian

Updated on September 18, 2022

Comments

  • basedian
    basedian almost 2 years

    I've a command that outputs data to stdout (command1 -p=aaa -v=bbb -i=4). The output line can have the following value:

    rate (10%) - name: value - 10Kbps
    

    I want to grep that output in order to store that 'rate' (I guess pipe will be useful here). And finally, I would like that rate to be a value of a parameter on a second command (let's say command2 -t=${rate})

    It looks to be tricky on my side; I would like to know better how to use pipes, grep, sed and so on.

    I've tried lots of combinations like that one but I'm getting confused of these:

    $ command1 -p=aaa -v=bbb -i=4 | grep "rate" 2>&1 command2 -t="rate was "${rate}
    
  • David Ferenczy Rogožan
    David Ferenczy Rogožan over 4 years
    So grep will just output some value but the question is how to use that value as a parameter of another command. Unfortunately, that important part is missing in your answer.
  • KFL
    KFL over 2 years
    No, it would be useful to have what OP asked - many times we don't get to control how a tool passes its output or accepts its input. Some decided via stdin/out, some uses arguments. It'd be very useful to have a way to glue those different tools together.
  • Admin
    Admin about 2 years
    @KFL see my answer gluing together with pipes and xargs