我如何把" \ s | ="作为awk中的字段分隔符?

时间:2018-06-18 11:26:55

标签: awk

这有效:

awk  -F"[[:space:]]|=" '/^[^#]/{print($2)}'   /etc/fstab 

但这并不是:

awk  -F"\s|=" '/^[^#]/{print($2)}'   /etc/fstab 

我正在使用awk与Ubuntu 16.04一起使用。

2 个答案:

答案 0 :(得分:1)

欢迎使用bash转义序列的噩梦,并在awk中将字符串常量用作正则表达式。您定义了一个双引号字符串,用作awk(Solving environment: failed UnsatisfiableError: The following specifications were found to be in conflict: - python-dateutil -> python[version='>=2.7,<2.8.0a0'] - python-dateutil -> six - python==3.7 Use "conda info <package>" to see the dependencies for each package. )中的正则表达式。

awk如何处理正则表达式:

首先,您需要了解有两种在awk中编写正则表达式的方法:

  • 您将其用斜杠-F"\s|="
  • 括起来
  • 您将其括在引号之间(例如用/ere/完成)

但是,后者意味着您的字符串将被解析两次:第一次是awk读取程序,第二次是它与字符串左侧的字符串匹配。运算符,其模式在右侧(请参见GNU awk manual)。

因此,表达式FS/\s|=/是等效的正则表达式,而"\\s|="/s|=/是等效的。

bash如何处理"\s|="

Bash使用\字符来转义字符。不带引号的反斜杠(\)保留下一个字符的文字值(极少数例外)。单引号反斜杠没有特殊含义,而双引号反斜杠仅在后面跟随以下字符之一时才保留其特殊含义:\$`,{{1 }}或"

这现在为我们提供了以下选项:

  • \:awk接收字符串表达式<newline>,该表达式被解析为正则表达式-F"\s|="
  • "\s|=":bash转义第二个/s|=/,awk接收字符串表达式-F"\\s|=",该表达式被解析为正则表达式\
  • "\s|=":bash替换第二个/s|=/,awk接收字符串表达式-F"\\\s|=",该表达式被解析为正则表达式\
  • "\\s|=":bash转义第二和第四/\s|=/,awk接收字符串表达式-F"\\\\s|=",该表达式被解析为正则表达式\

因此,以下内容都是等效的:

"\\s|="

  

共有三种报价机制:转义符,单引号和双引号。

     
      
  • 反引号(/\s|=/)是转义字符。它保留后面的下一个字符的文字值,$ awk -F '\\s|=' '/^[^#]/{print $2}' /etc/fstab $ awk -F "\\\s|=" '/^[^#]/{print $2}' /etc/fstab $ awk -F "\\\\s|=" '/^[^#]/{print $2}' /etc/fstab $ awk 'BEGIN{FS="\\s"}/^[^#]/{print $2}' /etc/fstab $ awk 'BEGIN{FS="\\s"}/^[^#]/{print $2}' /etc/fstab $ awk "BEGIN{FS=\"\\\\s|=\"}/^[^#]/{print \$2}" /etc/fstab 除外。如果出现\对,并且反斜杠本身未加引号,      <newline>被视为行连续符(也就是说,它已从输入流中删除并被有效忽略)。

  •   
  • 单引号中的字符保留引号中每个字符的字面值。即使在前面加上反斜杠,也不能在单引号之间引起单引号。

  •   
  • 双引号中包含字符会保留引号内所有字符的文字值,但\<newline>\<newline>$除外,以及启用历史记录扩展后的`。字符\!在双引号中保留其特殊含义。 反斜杠仅在其后跟以下字符之一时保留其特殊含义:$`$`"可以在双引号内加上反斜杠,从而将双引号引起来。如果启用,将执行历史记录扩展,除非使用反斜杠转义出现在双引号中的\<newline>前面的反斜杠不会被删除。

  •   
     

来源! QUOTING

部分

答案 1 :(得分:0)

Looking at the error it produces:

$ awk -F"\s|=" '/^[^#]/{print($2)}' /etc/fstab
awk: warning: escape sequence `\s' treated as plain `s'

You need to escape the \s properly. For example, this seems to work for me:

$ awk 'BEGIN { FS="\\s|=" } /^[^#]/{print($2)}'  /etc/fstab