我的字符串:
<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