2

I'm using GNU Awk 5.0.1 and I need to use [} or [) as FS. I can't make it work. Below is what I've tried.

root@u2004:~# echo test | awk -F '[}' '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F '[\}' '{printf}'
awk: warning: escape sequence `\}' treated as plain `}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F '[\\}' '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[\}/
root@u2004:~# echo test | awk -F '[}}' '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}}/
root@u2004:~# echo test | awk -F "[}" '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F "[\}" '{printf}'
awk: warning: escape sequence `\}' treated as plain `}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F "[\\}" '{printf}'
awk: warning: escape sequence `\}' treated as plain `}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}/
root@u2004:~# echo test | awk -F "[}}" '{printf}'
awk: fatal: invalid regexp: Unmatched [, [^, [:, [., or [=: /[}}/
root@u2004:~#

How can I do this?

2
  • 1
    do you want to use [} as one delimiter or [ OR } ? May 7 at 5:01
  • @RomeoNinov Use [} as one delimiter. May 7 at 6:05

3 Answers 3

14

Since any multi-character string used as the input field separator (FS) will be interpreted as a regular expression, the string has to be a valid regular expression.

awk -F '\\[}' '{ print }'

Nothing special has to be done with the }, but the initial [ has to be escaped to be matched as a literal left square bracket. You need two backslashes because using a single backslash, as in \[}, would escape the square bracket and would set the delimiter expression to [}, which is an invalid regular expression. You may alternatively use [[] in place of \\[, which matches a literal [ using a bracket expression but which does not save on typing and may be difficult to read.

I took the liberty of fixing the code too. The printf statement takes a format string as an argument and then one or more expressions to output. Since you don't provide a format string, you would get an error.

A shorter variant is to use 1 (or any non-empty, non-zero string). This would act as a test which is always true. A true test would trigger the default action, which is to print the current record (line).

awk -F '\\[}' '1'

... although this would not do anything exciting other than output each line of input. A more useful test of the delimiter value would be

awk -F '\\[}' '{ print $1 }'

... which prints the first field of each input record, e.g., {]ABC if the input is {]ABC[}{]123[}.

3

You can try construction like this:

awk -v FS='\\[\}'  ' {printf}' input_file

It just require "double" escape of [

for the record you can use variant of the construction like:

 awk 'BEGIN{ FS="\\[\}"}  ' {printf}' input_file

or

awk   ' {printf}' FS='\\[\}' input_file

Also construction like this will do the work:

awk -F '[[]}' '{printf}' input_file

The "list" of optional delimiter contain only [ and must be followed by }

P.S. Single printf do nothing in awk. You should add some parameters like formatting strings and variables to be printed. As mentioned in other answers if you want to print the entire line use '1' instead of '{printf}'

3
  • 1
    +1. -F '[[]}' works too (a bracket expression containing only a [, followed by a }). e.g. echo '123[}456' | awk -F '[[]}' '{print $1 "\n" $2}'
    – cas
    May 7 at 7:04
  • @cas, thank you. Will add it as option :) May 7 at 7:19
  • 1
    That gives a awk: warning: escape sequence `\}' treated as plain `}' warning with the OP's GNU awk 5.0.1. You may want to add a note that that {printf} (from the OP) doesn't make sense. May 8 at 9:17
2

I find bracket expressions usually provide the simplest solution to these awk(!)ward delimiter issues. So as per @cas's comment:

$ echo 'one[}two' | awk -F '[[]}' '{print $2}'
two

It is certainly worth getting familiar with bracket expression syntax. Even though it might not look it at first glance if you're not used to them, I find both the simplicity and utility usually much easier to write and read than, e.g. double escapes(!). And of course they can also be used in other utilities such as grep, etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.