我有以下shell命令:
awk -F'\[|\]' '{print $2}'
这个命令在做什么?使用as分隔符[sometext]
拆分为字段?
E.g:
$ echo "this [line] passed to awk" | awk -F'\[|\]' '{print $2}'
line
编者注:默认情况下,只有Mawk在Ubuntu上使用,会生成上面的输出。
答案 0 :(得分:4)
明显 意图是将文字 [
和]
视为字段分隔符,即每次出现[
和/或]
时将每个输入记录拆分为字段,使用样本行将this
作为字段1({{ {1}}),$1
为字段2(line
),$2
为最后一个字段( passed to awk
)。
这是通过使用交替($3
)的正则表达式(正则表达式)实现的,其中任何一方定义需要字段分隔符(分隔符):正则表达式中的|
和\[
来表示文字 \]
和[
,因为默认情况下, ]
和[
是所谓的元字符(具有特殊语法含义的字符)。
请注意,]
总是将awk
变量(FS
选项)的值解释为正则表达式。
但是,正确的表单是-F
:
'\\[|\\]'
也就是说,使用字符集($ echo "this [line] passed to awk" | awk -F'\\[|\\]' '{print $2}'
line
)而不是替换([...]
)的更简洁版本是:
|
请注意$ echo "this [line] passed to awk" | awk -F'[][]' '{print $2}'
line
在]
之前谨慎放置在封闭的[
内以使其正常工作,以及如何封闭 {{1}现在有特殊含义:它们包含一个集字符,其中任何一个匹配。
至于为什么[...]
需要 2 [...]
个实例:
作为孤立的正则表达式 ,\
会起作用:
'\\[|\\]'
与文字\[|\]
\[
与文字[
\]
是一个与其中一个匹配的替代。然而, Awk&#39> 字符串处理首先:
由于字符串中的]
处理,应该,将|
缩减为\
之前解释为正则表达式。
\[|\]
,被解释为正则表达式,只会匹配单个,文字 [|]
因此,健壮且可移植的方式是在字符串文字中使用[|]
时,如果要传递单 {{1} }作为正则表达式的一部分。
来自relevant section of the GNU Awk manual的引用总结得很好:
要在字符串中的正则表达式中获得反斜杠,您必须键入两个反斜杠。
[1] 实施差异:
不幸的是,在字符串文字中的正则表达式字符之前,至少有一个主要的awk实现在单个|
存在时转向 guesswork 。
BSD / macOS Awk和GNU Awk行为可预测,当发现单\\
- 带前缀的正则表达式元字符时,GNU Awk也会发出有用的警告:
\
Awk支持\
中包含的正则表达式文字,其使用绕过了双重逃避问题。
然而:
因此,即使\
原则等同于# GNU Awk: Predictable string-first processing + a helpful warning.
echo 'a[b]|c' | gawk -F'\[|\]' '{print $2}'
gawk: warning: escape sequence '\[' treated as plain '['
gawk: warning: escape sequence '\]' treated as plain ']'
c
# BSD/macOS Awk: Predictable string-first processing, no warning.
echo 'a[b]|c' | awk -F'\[|\]' '{print $2}'
c
# Mawk: *Guesses* that a *regex* was intended.
# The unambiguous form -F'\\[|\\]' works too, fortunately.
echo 'a[b]|c' | mawk -F'\[|\]' '{print $2}'
b
,您也可以不使用以下内容,因为正则表达式文字不能是分配给(特殊)变量/.../
:
/\[|\]/