我想从文本行中 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 相同(p
in 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 数字或\d
ASCII-plus-Unicode 数字。
https://docs.raku.org/language/regexes#Regexes
https://raku.org