Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top
awk '{ TEMPVAR="/usr/bin"; printf("%s", system("ls $TEMPVAR")); }' empty

In this example I'm trying to bring in the variable TEMPVAR into the system call. How would I do this?

What I'm aiming to do: I'm trying to use date -d $0 +%s in a system call that occurs every line of a file. However, I'm struggling with how to get that $0 value into the system call.

share|improve this question
up vote 8 down vote accepted

awk can access environment variables using the ENVIRON special array. However, while you can assign values to elements of that array, it is not passed in the environment of the commands executed by awk's system, | getline or print |. That ENVIRON array is only intended for awk to get the value of the environment variables it is passed.

You can do: system("ls " var), but beware that the string that is passed to awk's system() (or print | or | getline) is actually passed as an argument to sh -c, so it is interpreted as shell code.

For instance, if the awk var variable contains foo;rm -rf /, it will not tell ls to list the file called "foo;rm -rf /" but instead to list the file called foo and then the rm command will be run.

So, you may need to escape all the characters special to the shell in that var variable.

This could be done for instance with:

awk '
  function escape(s) {
    gsub(/'\''/, "&\\\\&&", s)
    return "'\''" s "'\''"
    cmd = "date -d " escape($0) " +%s"
    cmd | getline seconds
    print seconds

While that means running one shell and one date command per line, you might as well do the reading of the file with the shell itself:

while IFS= read <&3 -r line; do
  date -d "$line" +%s
done 3< the-file
share|improve this answer
For future readers that wonder why so many quotes and backslashes are used, this is because the snippet is a **shell command too. What you basically need to do is to put single quotes around the argument and substitute the single quotes in the argument by '\'' (end string, insert \', continue string). In an AWK script (file), it is sufficient to use gsub(/'/, "'\\''", s); return "'" s "'";, but for a "one-liner" command, the single quotes and backslashes must be escaped again as shown by Stephane. – Lekensteyn Nov 22 '13 at 21:46

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.