简体   繁体   中英

double and single quotes in wrapping awk codes

I'm trying to extract a string from a group of strings stored in a variable, say foo , in bash:

foo="I foobar you"

using awk , but I got different results when I wrapped awk with single and double quotes:

$ echo $foo | awk '{print $2}'
$ foobar

$ echo $foo | awk "{print $2}"
$ I foobar you

Could anyone tell me why ' and " cause different results when wrapping awk ?

It is because when using double-quotes the the shell tries to expand it as a positional parameter or a variable before passing it to awk. In your case it tries to expand $1 but finds no value for it, and so the expansion results to nothing and that's why you get the default print action in awk to print the whole line.

The reason why we single quote the awk commands is that we want a plain string and not modified/tampered by the shell by any means before processed by the Awk command itself which understands $1 as the first field (with default space delimiter)

According to shell quoting rules:

  • Single quotes (' ') protect everything between the opening and closing quotes. The shell does no interpretation of the quoted text, passing it on verbatim to the command.

    As in your code {print $2} passed on as it is to awk as an action:
    $ echo $foo | awk '{print $2}'
    $ foobar

  • Double quotes (“ “) protect most things between the opening and closing quotes. The shell does at least variable and command substitution on the quoted text. Different shells may do additional kinds of processing on double-quoted text. Because certain characters within double-quoted text are processed by the shell, they must be escaped within the text. Of note are the characters '$', ''', '\\', and '"', all of which must be preceded by a backslash within double-quoted text if they are to be passed on literally to the program.

    So you have to escape $ to get the value of second col as:
    $ echo $foo | awk "{print \\$2}"
    $ foobar
    otherwise awk is doing its default action of printing the whole line as in your case.

  • Fully agreed with @Ed Mortan regarding the best practice of quoting the shell variables. Although the double quotes are default, but if accidentally ….
    $ echo "$foo" with double quotes
    $ I foobar you

    $ echo '$foo' with single quotes
    $ $foo

  • Remember, quoting rules are specific to shell. The above rules only apply to POSIX-complaint, Bourne-style shells (such as Bash, the GNU Bourne-Again Shell). It has nothing to do with awk, sed, grep, etc…

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM