This question gets asked often enough that it deserves its own answer. This common question doesn't actually point to a shortcoming of [[awk]]: rather, it is almost always due to the way that shell quoting interacts with the singlequote character. === The Short Story Use octal [[escape sequence]]s ('\047') or printf ('printf "%c", 39'). Do not use hex escape sequences ('\x27') because they can interact badly with the surrounding text in different ways depending on your awk implementation. === The Rambling Tale In order to print out the string "it said 'Hello, World!' and then returned 0", one can run the following program: {{{ BEGIN { print "it said 'Hello, World!' and then returned 0" exit 0 } }}} However, when one attempts something similar on the command line: {{{ awk 'BEGIN{print "it said 'Hello, World!' and then returned 0";exit 0}' }}} ...the shell complains, because it tries to parse "Hello, World!" as a string of commands to be inserted between two singlequoted strings. The first thought one might have is to surround the program fragment in double quotes rather than single quotes, but this interacts very badly with awk's literal string syntax and the "$" field reference operator. ==== Hex Escapes: Bad Juju Frustratingly, the next most obvious solution - using hex-escaped characters - seems to work at first: {{{ awk 'BEGIN{print "it said \x27Hello, World!\x27 and then returned 0";exit 0}' }}} ...but this consistency is a sham. Try the following fragment instead in gawk, mawk and busybox awk and compare the results: {{{ awk 'BEGIN{print "\x27foo!\x27"}' }}} Note that [[mawk]] and busybox awk print the expected string, but that [[gawk]] returns a [[multibyte]] character. As mentioned in paragraph 3 of the Rationale section of the [[http://www.opengroup.org/onlinepubs/009695399/utilities/awk.html#tag_04_06_18|Open Group Base Specifications issue 6]], and as reiterated in the GNU awk manual in [[http://www.gnu.org/software/gawk/manual/html_node/Escape-Sequences.html|section 2.2 ("Escape Sequences")]], the '\xHH' hexadecimal notation is ambiguous because it allows more than two successive hex bytes to be specified. Unfortunately the precise behaviour when more than two bytes are given is allowed to be implementation dependent. ==== Octal Escapes: Great Personality, but... Fortunately we can always regress to stone knives and bearskins: octal [[escape sequence]]s are required to have a fixed length. {{{ awk 'BEGIN{print "\047foo!\047"}' }}} ==== Uses and Abuses of printf Or we could use printf: {{{ awk 'BEGIN{printf "%cfoo!%c\n", 39, 39}' }}} ...but then we have to start counting to make sure that all the [[escape sequence]]s have a corresponding number. gawk features [[http://www.gnu.org/software/gawk/manual/html_node/Printf-Ordering.html|a printf extension]] for re-using printf arguments according to a position specified in the string sequence..: {{{ awk 'BEGIN{printf "%1$cfoo!%1$c\n", 39}' }}} ...but that compromise is far too ugly for polite company, so let's pretend we didn't mention it. ==== Explicit Concatenation (oh my!) There is also the old fallback of putting a single quote character in its own variable and then using explicit string concatenation: {{{ awk 'BEGIN{q="\047";print q"foo!"q}' }}} ...but that gets ugly when dealing with a long string that contains many single quote characters. ==== Being Creative Other ways include: escaping the single quote in the shell ('\'') and writing the hex character at the end of a string: {{{ awk 'BEGIN{print "it said '\''Hello, World!'\'' and then returned 0"}' awk 'BEGIN{print "it said \x27""Hello, World!\x27"" and then returned 0"}' }}} ==== Do The Right Thing The cleanest way is simply to write the program in its own file. There may also be shell-specific ways for working around the quoting problem: please feel free to add them to this page if you know any. ====Feed the quote as a variable to awk Another way is to provide the quote to awk as a variable: --single quote {{{ awk -v q="'" 'BEGIN{print "it said " q "Hello, World!" q " and then returned 0"}' }}} --double quote {{{ awk -v q='"' 'BEGIN{print "it said " q "Hello, World!" q " and then returned 0"}' }}} ====Using bash's quoting($'string') {{{ awk $'BEGIN{print "it said \'Hello, World!\' and then returned 0";exit 0}' }}}
Summary:
This change is a minor edit.
Username: