我正在尝试使用awk获取令牌。但awk并不适用于分隔符“(”。为什么会发生这种情况?
echo "sad ads ( this should come" | awk -F"( " '{print $2}'
awk: fatal: Unmatched ( or \(: /( /
但如果尝试用“)”它正在运作。
echo "sad ads ) this should come" | awk -F") " '{print $2}'
this should come
这背后的原因是什么? gawk也给出了同样的结果。
答案 0 :(得分:3)
“这背后的原因是什么?”
请注意以下工作(全程使用GNU awk):
$ echo "sad ads ( this should come" | awk -F'\\( ' '{print $2}'
this should come
但以下情况并非如此:
$ echo "sad ads ( this should come" | awk -F'\( ' '{print $2}'
awk: warning: escape sequence `\(' treated as plain `('
awk: fatal: Unmatched ( or \(: /( /
awk
无法将\(
识别为有效的转义序列,并将其替换为简单但不平衡的(
。它确实接受'\\('
作为转义括号。
gawk
documentation解释说,Posix对于在常规字符之前出现反斜杠时会发生什么应该是有意的:
常规字符前的反斜杠
如果在字符串中将反斜杠放在常量之前 不是以前列出的其中一个字符,POSIX awk故意 留下未定义的事件。有两种选择:
剥去反斜杠 这就是Brian Kernighan的笨蛋和笨蛋。例如,“a \ qc”与“aqc”相同。 (因为这是一个容易犯的错误 介绍并错过,gawk警告你。)考虑'FS =“[ \ t] + \ | [\ t] +“'使用由空格包围的垂直条作为 字段分隔符。字符串中应该有两个反斜杠:'FS = “[\ t] + \ | [\ t] +”'。)
单独留下反斜杠 其他一些awk实现就是这样做的。在这样的实现中,键入“a \ qc”与键入“a \ qc”相同。
(
不是常规角色,但显然,gawk根据前一种情况对待它。
shell和awk的交互有一个单独的问题。请注意,下面的两个命令仅在使用单引号和双引号时有所不同:
$ echo "sad ads ( this should come" | awk -F'\\( ' '{print $2}'
this should come
$ echo "sad ads ( this should come" | awk -F"\\( " '{print $2}'
awk: warning: escape sequence `\(' treated as plain `('
awk: fatal: Unmatched ( or \(: /( /
shell将"\\"
视为单个反斜杠,但将'\\'
视为两个反斜杠。
答案 1 :(得分:1)
将特殊字符包含在字符类
中echo "sad ads ( this should come" | awk -F"[(] " '{print $2}'