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 Answers 3

1

You need single quotes:

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

will return 2

1
  • Thank you! I was getting crazy! Jun 19, 2020 at 9:35
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
6
  • 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, 2020 at 9:48
  • I'm referring to the awk pattern/commands which does use single quotes.
    – DavidPostill
    Jun 19, 2020 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, 2020 at 10:22
  • @ruud Ah. OK....
    – DavidPostill
    Jun 19, 2020 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. Jun 22, 2020 at 12:47
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .