使用awk和regexp过滤列

Nic*_*ick 16 regex awk

我有一个非常简单的问题.我有一个包含多个列的文件,我想使用awk过滤它们.

所以感兴趣的列是第6列,我想找到包含以下内容的每个字符串:

  • 从1到100的数字开始
  • 在那之后"S"或"M"
  • 再次从1到100的数字
  • 在那之后"S"或"M"

所以每个例子:20S50M都可以

我试过了 :

awk '{ if($6 == '/[1-100][S|M][1-100][S|M]/') print} file.txt
Run Code Online (Sandbox Code Playgroud)

但它不起作用......我做错了什么?

Chr*_*our 41

这应该做的伎俩:

awk '$6~/^(([1-9]|[1-9][0-9]|100)[SM]){2}$/' file
Run Code Online (Sandbox Code Playgroud)

Regexplanation:

^                        # Match the start of the string
(([1-9]|[1-9][0-9]|100)  # Match a single digit 1-9 or double digit 10-99 or 100
[SM]                     # Character class matching the character S or M
){2}                     # Repeat everything in the parens twice
$                        # Match the end of the string
Run Code Online (Sandbox Code Playgroud)

你的陈述有很多问题:

awk '{ if($6 == '/[1-100][S|M][1-100][S|M]/') print} file.txt
Run Code Online (Sandbox Code Playgroud)
  • ==是字符串比较运算符.正则表达式比较运算符是~.
  • 你没有引用正则表达式字符串(你从不引用awk脚本本身旁边带引号的任何东西)并且你的脚本缺少最终(合法)单引号.
  • [0-9]是数字字符的字符类,它不是数字范围.这意味着匹配类中的任何字符而0,1,2,3,4,5,6,7,8,9不是范围内的任何数值,因此[1-100]不是数字范围1 - 100中的数字的正则表达式,它将匹配1或0.
  • [SM]相当于(S|M)你所尝试的[S|M]是相同的(S|\||M).您不需要字符类中的OR运算符.

awk使用以下结构condition{action}.如果条件为True,则{}对正在读取的当前记录执行以下块中的操作.我的解决方案中的条件是$6~/^(([1-9]|[1-9][0-9]|100)[SM]){2}$/可读取的,第六列与正则表达式匹配,如果为True则打印行,因为如果没有得到任何操作,则默认awk执行{print $0}.

  • +1 表示“正则解释”的概念。我知道这是线程死灵法术,但此刻我正处于一个正则表达式的洞中,这让我笑了。:) (3认同)