0

I am having trouble printing (or searching) for sequences containing backslashes when using awk For example -

echo "test\test" | awk '{ gsub(/\\\\t/, "\\\\&"); print }'

will give the result:

test    est

because the \t will be interperted as tab. I want to be able to have the string as is, meaning:

test\test

The echo command is just another way for me to check a 1 liner for the awk command to see if it can find a pattern such as \t in a file (using a bash script). To be more sprcific - If I want to have an awk cmd that needs to find a sequence of

\"

I am using the following:

awk -v st="$match_string" 'BEGIN {gsub(/\\\\"/,"\\\\&", st)} match($0,st {print;exit}' file.txt

but the cmd does not work: for a file with :

547 %$ 
236 \"
4523 &* 
8876 (*
8756 "/
...

it will output:

> \"
8756 "/

What is the right way to use awk to find the

236 \"

Thanks

Kusalananda
  • 333,661
tomer
  • 1

2 Answers2

1

It's your echo that expands the \t into a tab character. Don't use echo to output strings that contain backslashes. Use printf instead.

printf '%s\n' 'test\test' | awk '{ print }'

See also:

  • Why is printf better than echo?

    The take-home message from there is

    POSIX says: if the first argument is -n or any argument contains backslashes, then the behaviour is unspecified.


Taking the updated question into account:

You want to match \" in the second column of some data, with the string \" given as an argument to the awk program:

string='\\"'
awk -v string="$string" '$2 == string' file

This would return

236 \"

given the data in the question. Note that you will have to escape the backslash since you need to expand the variable in the shell once when calling awk.

You may also use

string='\"' awk '$2 == ENVIRON["string"]' file

i.e., you pass the string as an environment variable into the awk program. In this case, the backslash does not need to be escaped.

To use a regular expression against the whole line, use either

string='\\\\"'
awk -v string="$string" '$0 ~ string' file

or,

string='\\"' awk '$0 ~ ENVIRON["string"]' file

Matching a backslash in a regular expression is done with \\, so this is what we have to pass to awk. Using awk -v, each backslash needs to be doubled up due to expanding the value of $string on the command line once in the call to awk.

Note also that if you had used double quotes to set the value of string when using awk -v to pass the string into the awk program, you would have had to double up all the double quotes again (since the shell acts on double quoted backslashes), and escape the double quote in the string:

string="\\\\\\\\\""
awk -v string="$string" '$0 ~ string' file

So, the first line here sets string to \\\\" in the shell, and the awk -v string="$string" will then evaluate to awk -v string='\\"' as we needed for matching a backslash and a double quote as a regular expression.

Kusalananda
  • 333,661
0

Just echo "test\\test" will do what you want , but if you prefer awk ,you can just print it like this :

$ echo "test\test" | awk ' { print }'
test\test