LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Simple AWK question (https://www.linuxquestions.org/questions/programming-9/simple-awk-question-906447/)

messinwu 10-04-2011 06:29 PM

Simple AWK question
 
Sorry to be asking such a simple question here, but I've been googling for an hour already and can't seem to find the answer, perhaps I'm not searching for the right thing.

I'm working on an AWK script, and I need it to execute a shell command and assign the output of that command to a variable for use inside the AWK script itself.

If I were writing a bash script or executing it on the command line, it would go like this:

Code:

./distance 41.4415477 -97.0653093 41.4416332 -97.0643041
...and the output is: 0.052398

I've tried using the system("./distance "coordinates) thing, but from what I've read, that only outputs an exit status. The distance script did invoke with this attempt, but the output was not assigned to a variable, it was just echoed to the terminal.

Tinkster 10-04-2011 06:47 PM

From the awk man page:
Code:

      command | getline [var]
                            Run command piping the output either into $0 or var, as above.




Cheers,
Tink

messinwu 10-04-2011 07:04 PM

no workie....

Code:

awk: ./test:34:    system("./distance "dist) | getline [distance]
awk: ./test:34:                                        ^ syntax error


messinwu 10-04-2011 07:18 PM

Got it! As usual, the man page was misleading or too vague to get on first try... This works:

Code:

"./distance " dist | getline distance

Tinkster 10-04-2011 07:34 PM

I didn't think it was vague or misleading there. No mention of HAVING to
use a system. command | getline, how much more explicit can it be? :}


Cheers,
Tink

messinwu 10-04-2011 07:45 PM

From the man page example, I was led to believe I needed to bracket my variable name, but that's what caused the syntax error. That's what I meant. Thanks for your help, though. It's much appreciated.

PTrenholme 10-04-2011 08:29 PM

If your requirements are more complex, here's the program I keep in /usr/share/awk so I can include it when I need to access system commands:
Code:

# cat /usr/share/awk/command_functions.gawk
##############################################################################################
#
# Functions defined in this file:
#      define_sucmd()
#              Sets the (global) variable "sucmd" to null or "sudo "
#      run_cmd(cmd)
#              Runs "cmd," returns error code (if any)
#              (See below for optional arguments)
#      su_run_cmd(cmd)
#              Runs "cmd" as "root" and returns error code (if any)
#              (See below for optional arguments)
#      cmd_result(cmd,  result_array)
#              Runs "cmd," returns result_array[1] - pass result_array if more results are desired.
#              (See below for other optional arguments.)
#      su_cmd_result(cmd,  result_array)
#              Runs "cmd" as "root" and returns result_array[1] - pass result_array if more results are desired.
#              (See below for other optional arguments.)
#
# NOTE: This code assumes that the global variable "exe" will contain the name of the program
#      (or the parent thereof) for display in some error messages.
#
##############################################################################################
##############################################################################################
#
# Define the prefix, if any, needed to run commands as root.
#
##############################################################################################
function define_sucmd(  id)
{
  if (! sucmd) {
  # Are we already running as "root"
    id=cmd_result("id -u")
    if (id == 0) {
      return
    }
  }
# If here we need "sudo" access. Note: If "sudo" times out, the password prompt will be re-displayed
  print "This program requires "root" access. Enter your password if prompted."
  run_cmd("sudo echo \"O.K.\"","Aborting",255)
  sucmd="sudo "
}
##############################################################################################
#
# Run a command.
# Print a message to stderr and exit on failure if exit_code != 0
# Note: Only the system() return code is returned. See cmd_result() for string/array returns
#
#############################################################################################
function run_cmd(\
  cmd,          # Command to be run\
# Optional arguments
  error_message,# Message to print if the command fails. Default: no message\
  exit_code,    # Exit code to use if the command fails. Default: Do not exit\
# Local variables
  ret)          # System call return value holder
{
  ret=system(cmd)
  if (ret) {
    if (error_message != "") print exe ": " error_message > "/dev/stderr"
    if (exit_code +0 != 0) exit(exit_code)
  }
  return ret
}
##############################################################################################
#
# Run a command as root.
# Note: Only the system() return code is returned. See cmd_result() for string/array returns
#
#############################################################################################
function su_run_cmd(\
  cmd,          # Command to be run\
# Optional arguments
  error_message,# Message to print if the command fails. Default: no message\
  exit_code)    # Exit code to use if the command fails..Default: Do not exit\
{
  define_sucmd()
  return run_cmd(sucmd cmd, error_message, exit_code)
}
##############################################################################################
#
# Run a command and return its output. If more than one result is returned by the system,
# the return value will be the first value returned by the command.
#
# If more than one value is desired, pass the optional array name as the second argument
# and set the third argument to "list."
#
#############################################################################################
function cmd_result(\
  cmd,          # Command to execute\
# Optional arguments\
  results,      # Array in which the results should be returned\
  expect,      # Expected result (either "fail" or "list") Default: Single returned value\
  error_message,# Error message if the command fails (or, if failure is expected, succeeds)\
# Local variables\
  result_string,\
  temp,\
  n)
{
  n = 0
  result_string=""
  while (cmd | getline temp) {
    ++n
    result_string = ((result_string) ? result_string SUBSEP : "") temp
  }
  close(cmd)
  if ( expect == "fail" && n > 0) {
    if (error_message) {
      print exe ": cmd_result(): " error_message > "/dev/stderr"
    }
    else {
      print exe ": cmd_result(): " cmd " did not fail." > "/dev/stderr"
    }
  }
  if ((n > 1) && (expect !="list")) {
    print exe ": Warning (cmd_result()): " cmd " returned " n " values."
  }
  split(result_string, results, SUBSEP)
  return results[1]
}
##############################################################################################
#
# Run a command as "root" and return its output. If more than one result is returned by the
# system, the return value will be the first value returned by the command.
#
# If more than one value is desired, pass the optional array name as the second argument
# and set the third argument to "list."
#
#############################################################################################
function su_cmd_results(\
  cmd,          # Command to execute\
# Optional arguments\
  results,      # Array in which the results should be returned\
  expect,      # Expected result (either "fail" or "list") Default: Single returned value\
  error_message)# Error message if the command fails (or, if failure is expected, succeeds)\
{
  define_sucmd()
  return cmd_result(sucmd cmd, results, expect, error_message)
}

Note that this code is not portable to standard AWK since it uses gawk extensions.

Tinkster 10-04-2011 09:11 PM

Quote:

Originally Posted by messinwu (Post 4490173)
From the man page example, I was led to believe I needed to bracket my variable name, but that's what caused the syntax error. That's what I meant. Thanks for your help, though. It's much appreciated.

In most GNU man pages I've come across square brackets indicate
an optional parameter, and are never used literally (unless they
explicitly are indicated to have syntactial meaning, e.g. in
regular expressions).


Cheers,
Tink


All times are GMT -5. The time now is 07:21 AM.