Assigning system command's output to variable

Viewed 95745

I want to run the system command in an awk script and get its output stored in a variable. I've been trying to do this, but the command's output always goes to the shell and I'm not able to capture it. Any ideas on how this can be done?

Example:

$ date | awk --field-separator=! {$1 = system("strip $1"); /*more processing*/}

Should call the strip system command and instead of sending the output to the shell, should assign the output back to $1 for more processing. Rignt now, it's sending output to shell and assigning the command's retcode to $1.

6 Answers

Note: Coprocess is GNU awk specific. Anyway another alternative is using getline

cmd = "strip "$1
while ( ( cmd | getline result ) > 0 ) {
  print  result
} 
close(cmd)

Calling close(cmd) will prevent awk to throw this error after a number of calls :

fatal: cannot open pipe `…' (Too many open files)

Figured out.

We use awk's Two-way I/O

{
  "strip $1" |& getline $1
}

passes $1 to strip and the getline takes output from strip back to $1

You can use this when you need to process a grep output:

echo "some/path/exex.c:some text" | awk -F: '{ "basename "$1"" |& getline $1; print $1 " ==> " $2}'

option -F: tell awk to use : as field separator

"basename "$1"" execute shell command basename on first field

|& getline $1 reads output of previous shell command in substream

output:
exex.c ==> some text

I am using macOS's awk and I also needed exit status of the command. So I extended @ghostdog74's solution to get the exit status too:

Exit if non-zero exit status:

cmd = <your command goes here>
cmd = cmd" ; printf \"\n$?\""

last_res = ""
value = ""        

while ( ( cmd | getline res ) > 0 ) {

    if (value == "") {
        value = last_res
    } else {
        value = value"\n"last_res
    }

    last_res = res
}

close(cmd)

# Now `res` has the exit status of the command
# and `value` has the complete output of command

if (res != 0) {
    exit 1
} else {
    print value
}

So basically I just changed cmd to print exit status of the command on a new line. After the execution of the above while loop, res would contain the exit status of the command and value would contain the complete output of the command.

Honestly not a very neat way and I myself would like to know if there is some better way.

Related