正则表达式将grep特定字符串后的数字


Answers:


14

尝试这个:

grep -oP '(?<=ID: )[0-9]+' file

要么:

perl -nle 'print $1 if /ID:.*?(\d+)/' file

感谢您的答复,但我不需要文件中的所有数字,仅需要ID后出现的数字:
Blake Gibbs 2014年

更新了我的答案。
cuonglm

1
请注意,-o-P是GNU对的扩展grep-o也可以在BSD上使用。对PCRE的支持-P并不总是在任何一个中进行编译。
马特

4

使用egrepwith -ogrepwith -Eo选项仅获取匹配的句段。使用[0-9]的正则表达式来得到的只是数字:

grep -Eo [0-9]+ filename

1
OP仅在特定字符串之后才需要将其匹配。请参阅问题标题。
terdon

4

很多方法可以做到这一点。例如:

  1. 将GNU grep与最近的PCRE一起使用,并匹配以下数字ID:

    grep -oP 'ID:\s*\K\d+' file
    
  2. 使用awk并仅打印以开头的所有行的最后一个字段ID:

    awk '/^ID:/{print $NF}' file
    

    这也将打印不是数字的字段,仅获取数字,并且仅在第二个字段中使用

    awk '($1=="ID:" && $2~/^[0-9]+$/){print $2}' file
    
  3. 将GNU grep与扩展正则表达式一起使用,并将其解析两次:

    grep -Eo '^ID: *[0-9]+' file | grep -o '[0-9]*'
    

谢谢!\K第一个示例在做什么?
rnd_d 2015年

2
@rnd_d是Perl兼容正则表达式(PCRE)的构造,表示“忽略到目前为止所有匹配的内容”。它的使用就像是向后看,它让我-o用来仅打印匹配的部分,但也丢弃我不感兴趣的内容。比较echo "foobar" | grep -oP "foobar"echo "foobar" | grep -oP 'foo\Kbar'
terdon

4
sed -n '/ID: 54376/,${s/[^ 0-9]*//g;/./p}'

那将只打印ID: 54376在任何文件输入之后出现的所有数字和空格。

我刚刚对上面的内容进行了一些更新,以便在删除非{numeric,space}字符后更快地进行处理,*并且不使p空白行变得粗糙。

它涉及从正则表达式线/ID: 54376/ ,通过$最后和他们s///删除所有或任何*字符^不是[^ 0-9]*那么prints /任何/一个行.字符剩余。

演示:

{
echo line 
printf 'ID: 54376\nno_nums_or_spaces\n'
printf '%s @nd 0th3r char@cter$ %s\n' $(seq 10)
echo 'ID: 54376'
} | sed -n '/ID 54376/,${s/[^ 0-9]*//g;/./p}'

输出:

 54376
1  03  2
3  03  4
5  03  6
7  03  8
9  03  10
 54376

1

使用sed:

{
    echo "ID: 1"
    echo "Line doesn't start with ID: "
    echo "ID: Non-numbers"
    echo "ID: 4"
} | sed -n '/^ID: [0-9][0-9]*$/s/ID: //p'

-n是“默认不打印任何”时,/^ID: [0-9][0-9]*$/是“匹配此正则表达式线”(开始于“ID:”,然后1个或多个数字,然后结束线的),并且s/ID: //p具有以下形式s/pattern/repl/flags- s手段我们正在执行替换,请使用标志将模式"ID: "替换为替换文本""(空字符串)p,这意味着“替换后打印此行”。

输出:

1
4

如果ID位于行中心,则无法使用。
Avinash Raj 2014年

根据我对问题的理解,也不应这样做。而且,不尝试过早处理这种情况会使代码更简单,更可移植。
godlygeek

0

另一个GNU sed命令,

sed -nr '/ID: [0-9]+/ s/.*ID: +([0-9]+).*/\1/p' file

它在之后打印任何数字 ID:


您真的不需要+。如果一个字符和三个字符之间的差异是您的脚本可能无法在所有代码中都起作用,则您可能sed应该这样做:sed -n '/ID: \([0-9][0-9]*\).*/{s//\1/;s/.*[^0-9]//;/./p}'。您的答案还会错过ID: [0-9]包含两次出现的行中的第一个ID: [0-9]
mikeserv

0

使用grep + awk:

  grep "^ID" your_file | awk {'print $2'}

奖金:易于阅读:)


1
grep如果您使用,则不需要awkawk '/^ID/ { print $2 }'做同样的事情,并避免了grep行缓冲问题。它也与@terdon的答案中的一种解决方案几乎相同。
cas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.