很难 grep。我该如何隔离这个数字?

很难 grep。我该如何隔离这个数字?

我有这个文件内容:

  63 41,3,11,12 
  1 31,60,72,96 
  7 41,3,31,14,15,68,59,60 
  7 60,72,96 
  7 60 
  1 41,3,31,31,14,15,68,59,60 
  60 41,3,115,12,13,66,96 
  1 41,3,11,12,13,66,96 

我需要在“60”之前grep“7”(其中“60”后面没有“72,96”)。

答案1

根据评论修改示例

$ cat ip.txt
  7 60,72,96 
  7 60 
3 601
 2 60,72,962
5 60,3
43 60   
3 52360

$ grep -oP '^\h*\K\d+(?=\h+60\h*$)' ip.txt 
7
43
  • -oP仅打印匹配部分,使用 PCRE
  • ^\h*\K忽略行的起始空白字符
  • \d+要打印的数量
  • (?=\h+60\h*$)仅当其后跟有空白字符时,然后60是可选的空白,直到行尾

或者,仅用于awk基于字段的处理;)

答案2

仅将第一个字段从第二个字段所在的行中取出60(应该适用于任何 awk,而不仅仅是 GNU awk):

awk '$2 == "60" {print $1}' < file 

或者与grepsed

grep -E '^[[:space:]]*[[:digit:]]+[[:space:]]+60[[:space:]]*$' < file |
   sed -e 's/^[[:space:]]*//' -e 's/[[:space:]].*//'

awk 中的一个丑陋的单行语句,适用于一般情况,即您想要包含60但要精确排除也具有该对的行72,96

awk 'function f(n) { return ($2 ~ "(^|,)" n "(,|$)") }
     f(60) && ! (f(72) && f(96)) {print NR, $1}' < file 

该函数f(n)检查是否n在第二个字段中的数字列表内(假设数字用逗号或字段的开头/结尾分隔)。然后我们只检查是否60存在,而该对72,96不存在。输出是行号 ( NR) 和第一个字段,但如果您不需要,可以轻松删除行号。

答案3

尝试:

$ cat infile
63 41,3,11,12 
  1 31,60,72,96 
  7 41,3,31,14,15,68,59,60 
  7 60,72,96 
  7 60 
  1 41,3,31,31,14,15,68,59,60 
  60 41,3,115,12,13,66,96 
  1 41,3,11,12,13,66,96   7 60,72,96 
  7 60 
3 601
 2 60,72,962
5 60,3
43 60   
3 52360

$ grep -oP '^\s*[0-9]+(?= 60\s*$)' infile
  7
  7
43   

描述:

grep -P '^             # grep from start of line
\s*                    # followed by optional spaces
[0-9]+                 # followed by some decimal digits
(?= 60\s*$)            # That have a <space>60<space(s)><end of line>
                       # but do not capture the 60.
' infile

答案4

我们可以使用awk逗号分隔第二个空格分隔的字段。如果分割字段的结果是多个单个值,则没有意义,否则,如果它是 60,则打印第一个空格分隔的字段:

awk 'split($2, a, ",") == 1 && $2 == 60 { print $1 }' <file

对于给出的示例数据,这将打印7

相关内容