Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.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
Linux 如何使用awk将文件中的多行版本号解析并打印为一行上的点分隔值_Linux_Bash_Awk_Pattern Matching_Printf - Fatal编程技术网

Linux 如何使用awk将文件中的多行版本号解析并打印为一行上的点分隔值

Linux 如何使用awk将文件中的多行版本号解析并打印为一行上的点分隔值,linux,bash,awk,pattern-matching,printf,Linux,Bash,Awk,Pattern Matching,Printf,我有一个文本文件(名为install.sh的mcafee agent安装脚本),其中包含许多行,包括我感兴趣的以下行: THIS_MAJOR=5 THIS_MINOR=0 THIS_PATCH=6 THIS_BUILD=491 我想使用awk将第2列中的数字打印在每行上,作为一行上的点分隔版本字符串,以便输出如下所示: 5.0.6.491 我正在使用以下awk命令匹配第2列中包含版本号的行,并打印值并将点字符附加到printf中: awk -F "=" '/^THIS_/ &&

我有一个文本文件(名为install.sh的mcafee agent安装脚本),其中包含许多行,包括我感兴趣的以下行:

THIS_MAJOR=5
THIS_MINOR=0
THIS_PATCH=6
THIS_BUILD=491
我想使用awk将第2列中的数字打印在每行上,作为一行上的点分隔版本字符串,以便输出如下所示:

5.0.6.491
我正在使用以下awk命令匹配第2列中包含版本号的行,并打印值并将点字符附加到printf中:

awk -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {printf("%s.", $2)}'  /tmp/install.sh
打印出:

5.0.6.491.
我试图避免打印最后一个“.”字符

这是我到目前为止试过的

使用gsub替换“.”字符。
不理想,因为我应该能够告诉awk,如果它在最后一行运行,就不要打印“.”

awk -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {printf("%s.", $2)} END{gsub(".","",$2)}' /tmp/install.sh
尝试使用结束而不打印最后一个“.”:

在包含版本号的行上不再正确匹配

尝试确定行数,在不处理最后一行的情况下,打印点字符,在最后一行不打印点字符

awk -v nlines=$(wc -l < $a) -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {printf("%s.", $2)} NR != nlines { printf("%s", $2)}' $a >> /tmp/install.sh
awk-v nlines=$(wc-l<$a)-F“=”/^此&/&/MAJOR&/MINOR |补丁|构建&&&&&/代理/{printf(“%s.”,$2)}NR!=nlines{printf(“%s”,$2)}'$a>>/tmp/install.sh
返回:

-bash:$a:不明确的重定向

如何使awk不打印最后一行数字的“.”字符


谢谢

我不确定我是否理解评论中的要求,但类似的方法会奏效,并且与您尝试的方法相差不远。您只需切换为在匹配项前加一个点,而不是在匹配项后加上一个点,然后跳过第一个点

awk -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {(output=="")? output=$2 : output=output"."$2} END {print output}'
匹配相同,逻辑更改为:
{(output==”)?output=$2:output=output.“$2}结束{print output}

它检查名为
output
的变量是否为空(它将在第一次匹配时为空),然后将其设置为
$2
,如果为空,则在
后面附加一个

e、 g


粘贴
用于此

$ awk -F= '/THIS_(MAJOR|MINOR|PATCH|BUILD)/{print $2}' file | paste -sd.
5.0.6.491

就我个人而言,我会这样做,这样输出的版本号与顺序无关。组成版本号部分的行出现在输入中,您可以简单地修改它,以打印以任何顺序添加到输入中的任何其他内容:

$ awk -F'=' -v OFS='.' 'sub(/^THIS_/,""){v[$1]=$2} END{print v["MAJOR"], v["MINOR"], v["PATCH"], v["BUILD"]}' file
5.0.6.491

我还想说明文本输入文件的未来更改。例如,如果删除或添加了一行,匹配行的数量会增加或减少。这对于我来说非常有效。它说明了对输入的更改。例如,通过添加一个字段“THIS\u MINOR2=1,或注释掉THIS\u BUILD=491,它仍然会按预期打印版本号。谢谢。
(output==”)?output=$2:output=output.“$2
写得更简洁,如
output=(output==”?:output“)$2
$ awk -F= '/THIS_(MAJOR|MINOR|PATCH|BUILD)/{print $2}' file | paste -sd.
5.0.6.491
$ awk -F'=' -v OFS='.' 'sub(/^THIS_/,""){v[$1]=$2} END{print v["MAJOR"], v["MINOR"], v["PATCH"], v["BUILD"]}' file
5.0.6.491