Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用awk/sed解析此特定字符串的最佳方法?_Sed_Awk_Grep - Fatal编程技术网

使用awk/sed解析此特定字符串的最佳方法?

使用awk/sed解析此特定字符串的最佳方法?,sed,awk,grep,Sed,Awk,Grep,我需要从文件中获取一个特定的版本字符串(称为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获取第一个版本(在本

我需要从文件中获取一个特定的版本字符串(称为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“APP1$”version.lst | awk'{print$1}'

$ awk '/^V1\.00.* APP1$/{print $NF}' version.lst
APP1
该正则表达式匹配以“V1.00”开头的行,后跟任意数量的任何其他字符,以“APP1”结尾。中间的反斜杠可能非常重要——它只匹配“.”,因此它排除了(可能是损坏的)可能以“V1A00”开头的行。“APP1”前面的空格不包括“APP2\u APP1”之类的内容

“NF”是一个自动生成的变量,包含输入行中的字段数。它也是最后一个字段的编号,恰好是您感兴趣的字段

有几种方法可以删除“V1”。这里有一个方法,尽管你和我可能谈论的不是完全相同的事情

$ awk '/^V1\.00.* APP1$/{print substr($1, 1, index($1, ".") - 1), $NF}' version.lst
V1 APP1

请尝试以下操作以获取完整版本:

#!/bin/sh
app=APP1
var=$(awk -v "app=$app" '$NF == app {print $1}' version.lst)
var=$(sed -n "/ $app\$/s/^\([^ ]*\).*/\1/p" version.lst)
或者仅获取主要版本号,最后一行可以是:

var=$(awk -v "app=$app" '$NF == app {split($1,a,"."); print a[1]}' version.lst)
使用
sed
获取完整版本:

#!/bin/sh
app=APP1
var=$(awk -v "app=$app" '$NF == app {print $1}' version.lst)
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,“.”)
    -然后在点处拆分第一个字段
  • 打印[1]
    -并打印拆分结果的第一部分
sed
命令:

  • -n
    -除非指示,否则不要打印任何输出
  • “/$app\$/
    -对于以(
    \$
    )结尾的任何一行,shell变量的内容
    $app
    (并非使用双引号来允许展开变量,最好转义第二个美元符号)
  • s/^\([^]*\)./\1/p“
    -从行首(
    ^
    )开始,捕获由任意数字(零个或多个
    *
    )的非空格(
    [^]
    )组成的字符序列,并匹配但不捕获行上的所有剩余字符(
    *
    ),将匹配的文本(本例中为整行)替换为捕获的字符串(版本号)(
    \1
    指第一个(本例中仅此一个)捕获组,并打印它(
    p

抱歉,忘了提到一些应用程序名称可能会重叠,因此您可能会有一个名为APP1的程序,然后是APP2\u APP1(可以不重叠,但其他应用程序名称可能包含另一个应用程序的名称),在这种情况下,我想这会打印出两个版本的IIRC。当然,egrep“-APP1$”这会解决这个问题,但我相信有一种更漂亮的方法。我只想在“APP1”之前加上一个。我想这样可以:)谢谢awk'{print$1}技巧,这很好。egrep是先得到问题行的唯一方法吗?然后sed/awk来处理/过滤它?问题稍有不同,但我如何使用awk只得到主要版本(即来自APP1行的V1)?感谢您使用awk和sed提供的多个答案(同时避免使用grep),将查看相应的文档,以了解它们到底在做什么,特别是对于sed,它看起来对我来说很陌生。感谢您对每个操作所做的回答和解释,这非常有帮助。