我需要从文件(称为version.lst)中获取特定版本的字符串,并使用它在Shell脚本中比较另一个字符串。例如,文件中包含如下所示的行:
V1.000 -- build date and other info here -- APP1
V1.000 -- build date and other info here -- APP2
V1.500 -- build date and other info here -- APP3
.. 等等。假设我正在尝试从APP1获取第一个版本(在本例中为V1.000)。显然,版本可以更改,我希望它是动态的。我现在所拥有的有效:
var = `cat version.lst | grep " -- APP1" | grep -Eo V[0-9].[0-9]{3}`
到grep的管道将获取包含APP1的行,而到grep的第二个管道将获取版本字符串。但是,我听说grep不是做到这一点的方法,所以我想学习使用awk或sed的最佳方法。有任何想法吗?我对这两者都不陌生,还没有找到一个容易学习它的语法的教程。他们支持egrep吗?谢谢!
最佳答案
尝试此操作以获取完整版本:
#!/bin/sh
app=APP1
var=$(awk -v "app=$app" '$NF == app {print $1}' version.lst)
或仅获取主要版本号,最后一行可能是:
var=$(awk -v "app=$app" '$NF == app {split($1,a,"."); print a[1]}' version.lst)
使用
sed
获取完整版本:var=$(sed -n "/ $app\$/s/^\([^ ]*\).*/\1/p" version.lst)
或仅获取主要版本号:
var=$(sed -n "/ $app\$/s/^\([^.]*\).*/\1/p" version.lst)
说明:
第二个AWK命令:
-v "app=$app"
-将AWK变量设置为等于shell变量$NF == app
-如果最后一个字段等于变量的内容(NF
是字段的数目,所以$NF
是第NFth字段的内容){split($1,a,".")
-然后在点print a[1]
-并打印分割后的sed
命令:-n
-除非定向到"/ $app\$/
-对于以(\$
)结尾的任何行,都包含shell变量$app
的内容(不是双引号用于允许扩展变量,并且转义第二个美元符号是个好主意)s/^\([^ ]*\).*/\1/p"
-从行的开头(^
)开始,捕获\(\)
包含由任意数字(零个或多个[^ ]
)组成的非空格(*
)(或第二个版本中的非点)的字符序列,并进行匹配但不要捕获该行(.*
)上的所有其余字符,请将匹配的文本(在本例中为整行)替换为捕获的字符串(版本号)(\1
指的是第一个字符(仅,在这种情况下)捕获组,然后将其打印(p
)关于sed - 使用awk/sed解析此特定字符串的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4846263/