How to escape backslash and double quotes with awk

2019-07-28 05:39发布

问题:

I have some awk that rearrange a line. I would like to escape one of the variables (e.g. $_), in such way that " and \ are escaped with a backslash.

Example:

echo "Ehm, \"hi\", he \\ said" | awk '{$1="" ; print "\"" $_ "\"" }'
" "hi", he \ said"

(do not change the echo, normally I read from a file that has Ehm, "hi", he \ said in it).

I would like to have

" \"hi\", he \\ said" 

instead. How can I do this? Is there a function in awk that can do this?

回答1:

Is there a reason you resort to awk? Bash is perfectly able to perform string manipulations:

#!/bin/bash

read -r ignored line <<<'Ehm, "hi", he \ said'
line=${line//\\/\\\\}
line=${line//\"/\\\"}
echo $line

Output

\"hi\", he \\ said


回答2:

Is this what you're looking for?

$ cat tst.awk
function foo(str) {
    sub(/^[^[:space:]]+/,"",str)   # remove first field
    gsub(/["\\]/,"\\\\&",str)      # put \ before each \ and "
    return "\"" str "\""           # surround with quotes
}
{ print foo($0) }

Test:

$ echo "Ehm, \"hi\", he \\ said" | awk -f tst.awk
" \"hi\", he \\ said"

$ cat file
Ehm, "hi", he \ said

$ awk -f tst.awk file
" \"hi\", he \\ said"


回答3:

When you pass a string with Bash, you have to take into consideration what echo itself is performing with the double quotes. Find it here:

$ echo "Ehm, \"hi\", he \\ said" | awk '1'
Ehm, "hi", he \ said

Using single quotes solves part of the problem:

$ echo 'Ehm, \"hi\", he \\ said' | awk '1'
Ehm, \"hi\", he \\ said

This being said, now it is time to add quotes around the string. For this, we use print with three arguments --> print "\"", $0, "\"".

To remove the first field, we can do it in the correct way:

$ echo 'Ehm, \"hi\", he \\ said' | awk '{sub(/^\S+\s*/, ""); print "\"", $0, "\""}'
"\"hi\", he \\ said"

If we just blank it, it looks like we get what your desired output was:

$ echo 'Ehm, \"hi\", he \\ said' | awk '{$1=""; print "\"", $0, "\""}'
" \"hi\", he \\ said"