Question

I've just been made into checking all my output files with gawk which I avoid as much as I can. How does

gawk 'NF \!= 6' file

differ from

gawk 'NF != 6' file 

that is, how does the backslash change the meaning of this expression?

Should it output lines with number of fields different than 6 and ending with backslash?

I'm getting the following error on my files:

gawk:    ^ backslash not last character on line

Anybody?

Was it helpful?

Solution

If you use double quotes instead of single quotes then ! is a special character and should be escaped with a backslash. Importantly, you are escaping the exclamation point so that your shell does not see it.

gawk "NF \!= 6" file

Within double quotes the shell will convert \! to ! before passing the argument to gawk. The backslash is gone by the time gawk is invoked.

With single qutoes, though, the shell will ignore ! characters, so there's no need to escape them with backslashes. In fact, as you found out it is a syntax error to do so since the backslash ends up being passed to gawk, which barfs on the unexpected \.

OTHER TIPS

The line without the backslash works as expected. However, if you want to know, backslash is used usually to scape special characters (they lose their special meaning and are used as themselves), and also to split long lines, so you could write something like (under a shell):

$ gawk 'NF \
!= 6' file

and it would have the same effect.

Your example in particular is a little bit more tricky. You put the string within single quotes. This makes the shell not to modify what you write, and pass it to the program. If you use your backslash expression, gawk will find a '\' in a place where it has no meaning (in gawk it is only used to split long lines and to scape characters in strings). In the example I wrote with a backslash in two lines, gawk receives two lines split by a backslash (conceptually one line).

If you're trying to match lines that don't have 6 fields and that do end in a backslash, this is one way to do that:

gawk -v 'patt=\\\\$' 'NF != 6 && $0 ~ patt' file

Gawk (and other AWKs) have some complex rules regarding backslash escaping. That's why their are four backslashes in the preceding command. (The dollar sign represents the end of the input line from the data file as in any regex.)

Whether you use double or single quotes, if you are using a Bourne-like shell, gawk will see the program exactly as it appears between the quotes. Even in double quotes, both Bourne and csh-like shells only consume \ before characters that might need escaping (like $, and in the case of csh, ! - thus in csh this program would appear syntactically correct to gawk, though it still wouldn't do what you want).

! has no meaning to gawk in this context, so it gives an error. To "output lines with number of fields different than 6 and ending with backslash", use:

gawk 'NF != 6 && /\\$/' file

That is: match lines that don't have 6 fields, and which match \ immediately preceding end of line ($). The \ must be escaped with another backslash, because gawk too uses \ for escaping - though in the case of gawk, all \ (except those escaped by another \) are absorbed; those that don't escape a special character are simply elided.

With no associated action, the default action (print the line) will be taken when this conditional statement is satisfied.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top