Grep 文本行中字符串之前/之后的变量号

Grep 文本行中字符串之前/之后的变量号

我想从文本行中 grep 一个数字。

cat log.txt | grep "License term"

01/01/2024:00:30 License term is 123 days.

我只想将“减数”与此分开。有没有办法在匹配关键字之前/之后回显单词?就像“输出“is”之后的字符串”或“输出“days”之前的字符串”?

它很可能是相同的,但将来可能会改变。 (日志条目的格式或其他文字将被添加)

答案1

以下sed命令将查找 中 与log.txt正则表达式 匹配的任何行.*License term is \([0-9]*\) days\.$,即包含子字符串 的任何行License term is,后跟一个可选的正整数,后跟days.该行末尾的子字符串。当找到这样的行时,整行都会被整数替换,并输出修改后的行,从而有效地提取您所要求的数字。

sed -n 's/.*License term is \([0-9]*\) days\.$/\1/p' log.txt

另一种方法是使用awk.下面使用稍微不同的方法,仅匹配包含字符串的行License term,然后输出这些行上倒数第二个空格分隔的单词:

awk '/License term/ { print $(NF-1) }' log.txt

显然,您还可以grep与 eg结合使用cut,从包含字符串的行中删除第五个空格分隔的字段License term

grep -F 'License term' log.txt | cut -d ' ' -f 5

我在这里使用grep它的-F选项来表明我们正在使用字符串而不是正则表达式进行搜索。

答案2

使用 GNU grep,您可以使用-o-P选项,分别表示“仅打印该行的匹配部分”和“使用 Perl 兼容的正则表达式”。对于PCRE,我们可以使用\K这意味着“丢弃到目前为止匹配的任何内容”。结合所有这些,我们得到:

$ grep -oP 'License term is \K\d+' log.txt 
123

当然,这是否能够一致地工作取决于您在 中的其他内容log.txt,但它适用于您的示例。

答案3

pcre2grep(或其前身pcregrep):

pcre2grep -xo1 '\d\d/\d\d/\d\d\d\d:\d\d:\d\d License term is (\d+) days\.' < log.txt

将对这些行进行保守匹配,仅选择与该模式真正匹配的行x,并从那里输出与第一个o捕获组匹配的数字。1

或者与 perl 相同(pin pcre2grep):

perl -lne '
  print $1 if m{^\d\d/\d\d/\d\d\d\d:\d\d:\d\d License term is (\d+) days\.$}
  ' < log.txt

答案4

使用(以前称为 Perl_6)

~$ raku -ne '.put if s/ .* "License term is " (<[0..9]>*) " days." $/$0/;'  log.txt   

#OR:

~$ raku -ne '.put if s/ .* License \s term \s is \s (<[0..9]>*) \s days \. $/$0/;'  log.txt

#OR:

~$ raku -ne '.put if s/ .* License <.ws> term <.ws> is <.ws>  (<[0..9]>*) <.ws> days \. $/$0/;'  log.txt

或者:

~$ raku -ne 'if /License \s term/ { put .words[4] };'  log.txt

#OR:

~$ raku -ne 'put .words[4]  if /License \s term/;'   log.txt

或者:

~$ raku -e '$0.put for lines.match(/ "License term is "  ( \d+ ) /);'  log.txt 

#OR:

~$ raku -e '.put for lines.match(/ "License term is "  ( \d+ ) /);'  log.txt  

这些用 Raku 编写的答案在很多方面与已经发布的优秀答案sed相似。awk前两组答案使用-ne非自动打印逐行标志。在第一组中s///使用该形式。在第二组中,Raku 的words例程用于在空白处进行分割。在最后一组答案中,Raku 的lines例程用于查找/返回子项match

输入示例:

#dummy_line followed by blank line

01/01/2024:00:30 License term is 123 days.
#dummy_line

示例输出:

123

使用 Raku 正则表达式引擎还可以使用“捕获标记”以及前瞻/后瞻。有关详细信息,请参阅下面的第一个链接。此外,您还可以选择捕获<[0..9]>ASCII 数字或\dASCII-plus-Unicode 数字。

https://docs.raku.org/language/regexes#Regexes
https://raku.org

相关内容