Why can't I escape quote in gawk?

2019-07-13 11:15发布

I'm trying to do the following, but either I'm way too tired and can't think, or something weird is hapening with the escapes:

scanimage -L | gawk '/N650U/ {print gensub("[\'`]", "", "g", $2)}'
pipe bquote> 

标签: linux shell gawk
5条回答
闹够了就滚
2楼-- · 2019-07-13 11:52

The idiom to do this is to create a variable which contains the single quote and then use that:

scanimage -L | gawk '/N650U/ {print gensub(q"`", "", "g", $2)}' q="'"

However, since you are using it in a character class, that is not going to work so you'll need to do this:

scanimage -L | gawk '/N650U/ {print gensub("[`'\'']", "", "g", $2)}'
                    <--      1st pair       -->  <--   2nd pair  -->

Another alternative if using bash is to use $'' which does support escaping single-quotes

scanimage -L | gawk $'/N650U/ {print gensub("[`\']", "", "g", $2)}'

All you are doing in the 2nd case is creating a single-quote pair right before your literal single-quote, escaping the single quote so the shell doesn't interpret it and then make another single-quote pair after it.

Example with single-quote in a regex

$ echo $'foo`\'' | awk '{gsub(/[o`'\'']/,"#")}1'
f####

Example with single-quote outside a regex

$ echo "foo" | awk '{print q$0q}' q="'"
'foo'

Example with single-quote inside $''

echo $'foo`\'' | awk $'{gsub(/[o`\']/,"#")}1'
f####
查看更多
Bombasti
3楼-- · 2019-07-13 11:57

Shell '...' doesn't support backslash escapes. You'll have to use "..." instead, I'm afraid.

gawk "/N650U/ {print gensub(\"['`]\", \"\", \"g\", \$2)}\"

(Note that shell "..." does expand $ variables, so you need to escape that as well!)

查看更多
不美不萌又怎样
4楼-- · 2019-07-13 12:04

There's no special character in single quotes including backslash(\).

Enclosing characters in single quotes (') preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

You can change the command to:

$ scanimage -L | awk '/N650U/ {print gensub("['"'"'`]", "", "g", $2)}'
查看更多
三岁会撩人
5楼-- · 2019-07-13 12:04

The correct way to do this is simply:

scanimage -L | gawk '/N650U/ {print gensub(/[\047`]/, "", "g", $2)}'

It doesn't affect using \047 for a single quote but as an aside given all of the other posted solutions are using string delimiters, note the use of regexp delimiters instead of string delimiters around the regexp that is gsub()s first argument. It matters, see for example:

$ printf 'a\\tb\n' | awk '{sub(/\\t/,"X")}1'
aXb
$ printf 'a\\tb\n' | awk '{sub("\\t","X")}1'
a\tb
$ printf 'a\\tb\n' | awk '{sub("\\\\t","X")}1'
aXb

The only time to use string delimiters in a regexp context is when you need to concatenate a literal with a variable, e.g.:

awk '{sub("<"var">","")}1'

Look up string and regexp delimiters in the man page for details.

查看更多
Anthone
6楼-- · 2019-07-13 12:09
gawk '/N650U/ {print gensub("[\'`]", "", "g", $2)}'
     ^                         ^
     beginning of sq string       end of single quoted string

A bit ugly, but this works:

gawk '/N650U/ {print gensub("['"'"'`]", "", "g", $2)}'
查看更多
登录 后发表回答