如何隔离一行文本的一部分以便将其用作变量

Posted

技术标签:

【中文标题】如何隔离一行文本的一部分以便将其用作变量【英文标题】:How to isolate part of a line of text in order to use it as a variable 【发布时间】:2017-05-26 11:09:55 【问题描述】:

我正在创建 bash 脚本,想从文件中的一行检查程序的版本号,并用它来进行不同的检查和操作。

文件中的版本行如下所示(示例):

Program Version 1.3 

Program Version 1.3.1

它在不同版本的不同行上,但始终遵循相同的语法。如何删除第一部分并仅隔离版本号以便将其放入变量中?

【问题讨论】:

这是我最后使用的版本=find . -type f -name "filename" -exec grep -h 'Program Version' + | awk -F " " 'print $3' 【参考方案1】:

使用GNU grep-P 进行perl 风格的regEx 匹配,并使用-o 标志仅返回匹配模式。

grep -oP 'Program Version \K[^ ]*' file
1.3.1

将其保存在变量中

versionNo="$(grep -oP 'Program Version \K[^ ]*' file)"
printf "%s\n" "$versionNo"
1.3.1

使用perl regEx 本身,

perl -lne 'print "$1" if /^Program Version (\d.+)/' file
1.3.1

在变量中,

versionNo="$(perl -lne 'print "$1" if /^Program Version (\d.+)/' file)" file
printf "%s\n" "$versionNo"
1.3.1

使用GNU sed

sed -r 's/Program Version ([[:digit:]].+).*/\1/' file
1.3.1

versionNo="$(sed -r 's/Program Version ([[:digit:]].+).*/\1/' file)" file
printf "%s\n" "$versionNo"
1.3.1

【讨论】:

实际的 perl 示例不需要\k,因为您正在打印捕获组。【参考方案2】:

我猜你会得到Program Version 1.3.1,例如启动某种命令。好吧,试试这个:

#!/bin/bash
version=$(yourCommandWhichShowsVersion 2> /dev/null | egrep "^Program Version [0-9]" | awk 'print $3')

解释:

您需要启动显示版本的命令 您将输出重定向到 egrep,它搜索仅匹配以 ^ 开头的所有行 Program Version,而这个 [0-9] 是匹配一个数字。如果您不知道版本是 1.3 还是 1.3.1 还是 1,这就是您所需要的。 awk 将“选择”第二列(第一列是“程序版本”,第二列是版本号)

祝你好运!

【讨论】:

几乎没有理由将grep 的输出传送到awk。此外,awk 中的字段从 1 开始编号,因此您要查找字段 3,而不是字段 2。awk 可以过滤自己的输入。 ... | awk '/^Program Version [0-9]/ print $3'. 也许你是对的,它只能用 awk 来完成,但这是有效的!因为在“管道”到 awk 之后,输出只有 2 个数据列并且它可以工作!第二个是版本。我用一些不同的程序进行了测试,这些程序在帮助选项中显示了它的版本,并且它在所有情况下都有效。谢谢你的提示! :) 为什么它打印Version?为什么应该只有两个数据列? awk 'print $2' <<< 'Program Version 1' 将打印 Version,而不是 1 哇,对不起……你们俩都是对的。我的错误...我编辑了帖子。太感谢了。我在没有空格的情况下放入了我的测试 ProgramVersion :O 我实际上使用了很多类似的命令。我会将这个标记为最有用的,因为我使用了类似的解决方案,我觉得它干净且简单。我使用 find + grep 来接收带有我需要的版本的行,并在 AWK 中使用 -f 将字段分隔符定义为空格,并且我已经将版本号与其余结果分开。谢谢大家的回答。【参考方案3】:
Value=$(cat program.txt | grep Program\ Version\ | sed "s/Program \Version\ //g")

只需找到程序版本,然后用 sed 将其删除。

编辑:抱歉误读。删除版本号

【讨论】:

他说他不知道版本号……所以1.3不能在grep中。【参考方案4】:

我只想使用grepcut,因为模式是固定的:

# find the first occurrence of the line (-m 1) starting with the pattern (^) and 
# the third field (cut -f3) is the version
# this makes sure we ignore
#   a) multiple occurrences of the pattern, if any
#   b) occurrence of "Program Version" anywhere else on a line
# we make no assumption about the format of the version number
version=$(grep -m 1 "^Program Version " program.txt | cut -f3 -d' ')
if [[ -z $version ]]; then
    # version not specified
    # your exception handler here
fi

【讨论】:

【参考方案5】:

该问题的一些可能解决方案:

awkawk '/Program Version/print $3' file.txtgrepgrep -oP "Program Version \K[^ ]*" file.txtsedsed -n '/Program Version /s///p' file.txtperlperl -lane 'if (/Program Version/) print $F[2]' file.txt

(HTH) 希望这会有所帮助。

【讨论】:

【参考方案6】:

这是我最后使用的:

Version=`find . -type f -name "filename" -exec grep -h 'Program Version'  + | awk -F " " 'print $3'`

我使用 find + grep 接收包含我需要的版本的行,并在 awk 中使用 -f 将字段分隔符定义为空格,并将版本号与其余结果分开。谢谢大家的回答。

【讨论】:

以上是关于如何隔离一行文本的一部分以便将其用作变量的主要内容,如果未能解决你的问题,请参考以下文章

如何将其用作变量而不是字符串?

c++ 获取文件的一部分

如何声明 Linq 表达式变量以便将其作为 dbParameter 处理

如何将文本和查询结果组合为 PHP 变量的值

将命令行变量写入文本文件

r 清理字符串,以便它们可以用作变量名称或列名称