如何使 sed 第一次出现而不是最后一次出现?

如何使 sed 第一次出现而不是最后一次出现?

我的字符串:

<p> <strong>Linux x86_64/AMD64/EM64T</strong><br> Latest Long Lived Branch Version: <a href="https://www.nvidia.com/Download/driverResults.aspx/163238/en-us">450.66</a><br> Latest Short Lived Branch Version: <a href="https://www.nvidia.com/Download/driverResults.aspx/150803/en-us">435.21</a><br> Latest Legacy GPU version (390.xx series): <a href="https://www.nvidia.com/Download/driverResults.aspx/160182/en-us">390.138</a><br> Latest Legacy GPU version (340.xx series): <a href="https://www.nvidia.com/Download/driverResults.aspx/156163/en-us">340.108</a><br> Latest Legacy GPU version (304.xx series): <a href="https://www.nvidia.com/Download/driverResults.aspx/123709/en-us">304.137</a><br> Latest Legacy GPU Version (71.86.xx series): <a href="https://www.nvidia.com/object/linux-display-amd64-71.86.15-driver.html">71.86.15</a><br> Latest Legacy GPU Version (96.43.xx series): <a href="https://www.nvidia.com/object/linux-display-amd64-96.43.23-driver.html">96.43.23</a><br> Latest Legacy GPU Version (173.14.xx series): <a href="https://www.nvidia.com/Download/driverResults.aspx/71303/en-us">173.14.39</a><br> <a href="https://www.nvidia.com/object/linux-amd64-display-archive.html">Archive</a></p>

通过管道将该字符串sed 's|^.*">\([0-9\.]*\)<.*$|\1|'生成173.14.39最后一个版本号。但我想要450.66哪个是第一个版本号。如何编辑上述sed参数来实现这一目标?

我还是个初学者sed,所以请详细一点。

答案1

由于.*是贪婪的,因此在表达式的其余部分匹配任何内容之前,它将尽可能多地匹配。这就是为什么你会得到最后一场比赛而不是第一场比赛。

解决方法是进行两次替换。一个删除所需数字后面的所有 HTML 标记,另一个删除剩余字符串开头的标记:

$ sed -e 's/\([[:digit:]]\)<.*/\1/' -e 's/.*>//' file
450.66

第一个表达式 ,s/\([[:digit:]]\)<.*/\1/将字符串的末尾替换为紧邻字符之前找到的第一个数字<。我们保证字符串将在以下位置被截断第一的[[:digit:]]<自从我们使用以来的匹配.* 那个图案。

这个表达式给我们留下了

<p> <strong>Linux x86_64/AMD64/EM64T</strong><br> Latest Long Lived Branch Version: <a href="https://www.nvidia.com/Download/driverResults.aspx/163238/en-us">450.66

第二个表达式s/.*>//,只是截断从字符串开头到最后一个>字符的所有内容。在这里,我们依靠尽可能.*多地匹配开始字符串的。

答案2

你可以awk这样使用:

awk -F 'en-us">|</a>' '{print $2}'

-F选项指示awk使用en-us"></a>作为字段分隔符而不是默认值来分割行。

然后只需打印正确的字段即可。在本例中,它是带有 的第二个字段print $2

这一切都假设您的示例字符串不会改变。

答案3

有几种方法可以对抗贪婪。这可以通过 2 个步骤完成。第一个是删除第一场比赛之后出现的所有内容,第二个是删除比赛之前出现的所有内容

sed -r 's/([0-9]+\.[0-9][^<]*).*/\1/; s/.*>(.*)$/\1/' file

下一个方法是通用的。它允许您选择字符串中的任何模板

sed -r 's/(>[0-9]+\.[0-9][^<]*)/\1\r/8; s/.*>(.*)\r.*/\1/' file
173.14.39

\r我们根据替换命令中指定的编号在模板末尾放置一个标志,然后根据该标志进行选择。这些示例使用模板 1 和 2。用数字进行实验

sed -r 's/(>[0-9]+\.[0-9][^<]*)/\1\r/2; s/.*>(.*)\r.*/\1/' file
435.21
sed -r 's/(>[0-9]+\.[0-9][^<]*)/\1\r/1; s/.*>(.*)\r.*/\1/' file
450.66

答案4

awk 命令

awk -F "en-us" '{gsub(/<.*/,"",$2);print $2 }' l| awk '{gsub(/^">/,"",$0);print }'

Python

#!/usr/bin/python
import re
o=re.compile(r'<.*')
k=open('l','r')
for i in  k:
    j=i.split("en-us")[1]
    print re.sub(o,"",j).replace('">','')

输出

450.66

相关内容