我在文件中有一行是这样的:
<TD><TR> monogram ended in 1 </TD></TR>
monogram ended in
始终是常数,但不是1
,该数字始终变化并且最多可以是 3 位数字。
所以我需要一个命令来搜索monogram ended in
并获取该字符串后面的数字。
有人能帮我一下吗。
答案1
你可以sed
这样使用:
sed -n 's/.*monogram ended in \([0-9]*\).*/\1/p' filename
- 使用
-n
,您可以抑制正常输出 - ubstitute命令
s
将整行(.*
开头和结尾)替换为\1
,这是里面的部分\(\)
,即数字 - 该
p
标志打印匹配中的替换
答案2
grep 的 GNU 实现有一个-P
选项,它启用一组被描述为“Perl 兼容正则表达式”的正则表达式。这些有\K
,可用于按照您想要的方式减少输出:
grep -Po 'monogram ended in \K\d+' filename
- 该
-P
选项启用 Perl 风格的正则表达式 - 该
-o
选项告诉 grep 仅输出该行的匹配部分(而不是整行) - 正则表达式与您描述的行匹配,即“以”结尾的字母组合,后跟数字
- 该
\K
表达式告诉 grep 使用整个正则表达式来匹配该行,但只写出该表达式后面的部分\K
- 表达式
\d+
匹配一个或多个数字
我上面的示例并不将匹配限制为三个连续数字。如果您想这样做,最有效的表达式是:
grep -Po 'monogram ended in \K\d{1,3}(?!\d)' filename
- 表达式
\d{1,3}
匹配一位、两位或三位连续数字 - 该
(?!\d)
表达式查看数字后面的位置以确保它不是数字(可能是字符,也可能是行尾),确保具有 4 个以上连续数字的行不会被匹配
答案3
使用乐(以前称为 Perl_6)
raku -ne 'put $/ if m/ <?after "monogram ended in" \s > \d+ /;'
如果您需要处理 Unicode 字符(内置强大的 Unicode 支持),Raku 是一个不错的选择。上面的打印$/
(Raku 的匹配变量,或者$<>
)。该代码使用零宽度正向回顾断言 ( <?after … >
),假设每行匹配一个,并删除不匹配的行。
如果您想要未找到匹配项的空行,请使用以下代码:
raku -ne 'if m/ <?after "monogram ended in" \s > \d+ / {put $/} else {put ""};'
您可以使用 Raku 的正则表达式量词来限制匹配数字的范围**
,例如:\d**1..3
or<digits>**1..3
只会返回长度为 1 到 3 位数字的匹配项。但由于行是从左到右读取的,因此数字超过 3 位的匹配行将在右端被截断。因此,简单地添加量词可能不会给您预期的结果:要正确执行此操作,您必须在右端添加一个非数字正则表达式原子:
raku -ne 'put $<> if m/ <?after "monogram ended in " > <digit>**1..3 <!digit> /;'
输入示例:
<TD><TR> monogram ended in 1 </TD></TR>
<TD><TR> duogram ended in 2 </TD></TR>
<TD><TR> monogram ended in 4444 </TD></TR>
示例输出(最终代码示例):1
答案4
假设输入是 XML 并且节点以正确的方式排序,如下所示
<?xml version="1.0"?>
<root>
<TR>
<TD>monogram ended in 1</TD>
</TR>
</root>
(在问题中交换了TR
和节点的开始标签),然后我们可以使用 XML 解析器来提取在作为节点的子节点的任何节点之后出现的值的部分,如下所示:TD
xmlstarlet
monogram ended in
TD
TR
xmlstarlet sel --template \
--match '//TR/TD[starts-with(text(),"monogram ended in ")]' \
--value-of 'substring-after(text(),"monogram ended in ")' -nl file.xml
TD
对于作为节点的直接子节点TR
且具有以字符串开头的值的每个节点monogram ended in
,这会提取该字符串后面的文本,然后添加换行符。
对于这样的示例文档:
<?xml version="1.0"?>
<root>
<TR>
<TD>monogram ended in 1</TD>
<TD>monogram ended in 2</TD>
<TD>monogram ended in 3</TD>
</TR>
<TR>
<TD>monogram ended in A</TD>
<TD>monogram ended in B</TD>
<TD>monogram ended in C</TD>
</TR>
</root>
...该命令将输出
1
2
3
A
B
C