2

I want to isolate the second column.

If I do:

echo "1  2 3" | awk "{ print $2 }"

the result is:

1  2 3

The expected result is:

2

I've tried with -F' ' option, but the result is the same.

What am I doing wrong?

3 Answers3

1

You need single quotes:

echo "1 2 3" | awk '{ print $2 }'

will return 2

Setanta
  • 126
1

What am I doing wrong?

echo "1  2 3" | awk "{ print $2 }"

The correct command is

echo "1  2 3" | awk '{ print $2 }'

Or

echo "1  2 3" | awk "{ print \$2 }"

Example:

$ echo "1  2 3" | awk '{ print $2 }'
2
$ echo "1  2 3" | awk "{ print \$2 }"
2
DavidPostill
  • 156,873
  • 3
    No; awk uses double quotes in its own scripts, but this is irrelevant here. Before awk starts running, the shell sees the double quotes and substitutes the value of whatever it knows as "$2", so awk runs with argument { print 1 2 3 }, which it obediently does. – tzot Jun 19 '20 at 09:48
  • I'm referring to the awk pattern/commands which does use single quotes. – DavidPostill Jun 19 '20 at 10:18
  • 1
    tzot is right. If you use double quotes, you have to escape the $ to prevent the shell from substituting it. echo "1 2 3" | awk "{ print $2 }". Awk will never know what kind of quotes were used. It gets the string w/o the quotes. – ruud Jun 19 '20 at 10:22
  • @ruud Ah. OK.... – DavidPostill Jun 19 '20 at 10:32
  • 1
    @tzot Yes, inside double quotes we must escape the $ in the shell context; that's right. However, in this specific case, the shell interprets $2 as blank: echo "1 2 3" | echo "[$2]" prints [], and the awk runs "{ print }", which will print the entire argument as it is. – Sony Santos Jun 22 '20 at 12:47
  • @SonySantos yes, you are absolutely correct! Thank you very much. – tzot Jun 22 '20 at 14:29
1

A correct approach has been already given in two other answers:

echo "1  2 3" | awk '{print $2}'

The "why", though, was lacking, so I am adding it.

echo "1  2 3" | awk "{print $2}"

fails because shells perform parameter expansion on $2. I.e., it retrieves the value of that variable, just as a=6;echo "$a" prints 6 in the command-line. From the POSIX shell manual,

Enclosing characters in double-quotes ( "" ) shall preserve the literal value of all characters within the double-quotes, with the exception of the characters backquote (`), dollar-sign ($), and backslash (\).

Unless your shell was started with arguments (highly unlikely scenario), $2 expands to the null string and awk never sees $2, just {print }, thus printing the whole 1 2 3 string.

Bear in mind that it is false to say that the awk program must be enclosed in single-quotes. Awk just needs to get its bytes and could not care less about what steps the shell takes to deliver them. So, these are also correct:

echo "X  Y Z" | awk "{print \$2}"
echo "X  Y Z" | awk \{print\ \$2\}

Yikes! I said it was correct, not clean.

Conclusion: Surround the awk program in single-quotes whenever possible.