我有这个文件内容:
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
或者与grep
和sed
:
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
。