使用正则表达式获取值范围

时间:2016-10-04 18:59:25

标签: regex awk

我试图编写两个awk命令来检查文件以满足这两个条件。

  1. 第一个条件是它将输出任何具有&n = deny = n'其中n为0或大于10,并忽略已注释掉的行。
  2. 示例:

    test deny=1
    test2 deny=0
    test deny=4
    #test=3 deny=0
    test deny=44
    

    我希望它显示:

    test deny=44
    test2 deny=0
    

    这是我当前的正则表达式似乎没有正确输出:

    awk '$1 ~ /[^#]*/ && ! /deny=([1-9]|10)/' /etc/pam.d/system-auth
    
    1. 我的第二个问题我想只显示deny = n的行,其中n是1-10之间的任何值。
    2. 这是此输出的当前行

      awk '$1 ~ /[^#]*/ &&  /deny=1[1-9]/ &&  /deny=[2-9][0-9]/' /etc/pam.d/system-auth
      

      有关如何改善这些的任何想法?在尝试将它移植到ruby之前,我想在shell / bash中看到它是如何工作的。

3 个答案:

答案 0 :(得分:1)

您可以将此awk命令与自定义字段分隔符一起使用:

awk -F '[= \t]+' '!/^[ \t]*#/ && $2 == "deny" && ($3==0 || $3>10)' file

test2 deny=0
test deny=44
  • -F '[= \t]+'将输入字段分隔符设置为=或空格或制表符
  • !/^[ \t]*#/将匹配未评论的任意行

修改

根据以下评论,如果deny可以出现在输入中的任何位置,请使用:

grep -E '^([[:blank:]]*[^#].*)?deny=(0\b|1[1-9]|[2-9][0-9])' file

test2 deny=0
test deny=44

(0\b|1[1-9]|[2-9][0-9])将匹配0或任何大于10的2位数字。

答案 1 :(得分:1)

当人们说他们需要进行数字比较然后寻找一种用regexp来捣乱它的方法时,我总是感到惊讶。如果要比较数字,请使用数字比较:

$ awk 'match($0,/^[^#]*deny=([0-9]+)/,a) && (a[1]==0 || a[1]>10)' file
test2 deny=0
test deny=44

$ awk 'match($0,/^[^#]*deny=([0-9]+)/,a) && (a[1]>=1 && a[1]<=10)' file
test deny=1
test deny=4

上面使用GNU awk表示第3个arg匹配(),其他awks表示它是substr()或sub()和变量,例如:

$ awk '{n=$0} sub(/^[^#]*deny=/,"",n) && (n+0==0 || n+0>10)' file
test2 deny=0
test deny=44

$ awk '{n=$0} sub(/^[^#]*deny=/,"",n) && (n+0>=1 && n+0<=10)' file
test deny=1
test deny=4

请注意,您需要在非gawk版本中添加零,因为我们在n上执行的第一个操作是字符串1(sub())所以此时awk“知道”n 1}}包含一个字符串(尽管它看起来像一个数字,这就是gawk版本不需要这种特殊处理的原因)所以要在之后使用它作为数字我们需要通过执行一个明确地将它转换为数字数字操作(+)就可以了。

答案 2 :(得分:0)

  1. 字符串deny=44与正则表达式/deny=([1-9]|10)/匹配 - 您需要一个字锚:/deny=([1-9]|10)\>/
  2. 字符串#test=3与正则表达式/[^#]*/匹配,因为有零个或多个非&#34;#&#34;字符
  3. 你想要

    awk '$1 !~ /^#/ && ! /deny=([1-9]|10)\>/'
    

    看起来您可以从在线正则表达式教程中受益。见https://stackoverflow.com/tags/regex/info