【问题标题】:How to use a regex for the field separator in AWK?如何在 AWK 中使用正则表达式作为字段分隔符?
【发布时间】:2017-03-29 07:41:56
【问题描述】:

我阅读了another answer,它展示了如何使用-F 标志设置字段分隔符:

awk -F 'INFORMATION DATA ' '{print $2}' t

现在我很好奇如何使用正则表达式作为字段分隔符。我的尝试如下所示:

$ echo "1 2 foo\n2 3 bar\n42 2 baz"
1 2 foo
2 3 bar
42 2 baz
$ echo "1 2 foo\n2 3 bar\n42 2 baz" | awk -F '\d+ \d+ ' '{ print $2 }'
# 3 blank lines

我希望得到以下输出:

foo
bar
baz 

这是因为我的正则表达式\d+ \d+ 匹配“前两个数字用空格分隔,后跟一个空格”。但我正在打印第二张唱片。如图rubular:

  • 如何使用正则表达式作为 awk 字段分隔符?

【问题讨论】:

标签: regex bash unix awk


【解决方案1】:

首先echo 不会自动转义并输出文字\n。所以你需要添加-e 来启用转义。其次awk不支持\d所以你必须使用[0-9][[:digit:]]

echo -e "1 2 foo\n2 3 bar\n42 2 baz" | awk -F '[0-9]+ [0-9]+ ' '{ print $2 }'

echo -e "1 2 foo\n2 3 bar\n42 2 baz" | awk -F '[[:digit:]]+ [[:digit:]]+ ' '{ print $2 }'

两个输出:

foo
bar
baz 

【讨论】:

  • 4 秒差!
  • 该死!甚至最终看起来完全一样! :)
  • 仅供参考,某些版本的 echo 会在给定 \n 的情况下打印文字换行符。这就是最好避免使用 echo 的原因之一——它的行为是不可移植的。请改用printf
【解决方案2】:

只需将\d 替换为[0-9]

有了这个,你可以打印所有的字段,你可以立即看到这些字段:

$ echo -e "1 2 foo\n2 3 bar\n42 2 baz" |awk -v FS="[0-9]+ [0-9]+" '{for (k=1;k<=NF;k++) print k,$k}'
1 
2  foo
1 
2  bar
1 
2  baz

所以只需在命令中使用 [0-9]:

$ echo -e "1 2 foo\n2 3 bar\n42 2 baz" |awk -v FS="[0-9]+ [0-9]+" '{print $2}'
 foo
 bar
 baz

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-27
    • 2015-08-22
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多