有效地从文件中提取值

时间:2019-02-21 16:08:42

标签: regex bash awk sed sh

假设我有此文件:version.h

#define MAJ_VERSION         1
#define MIN_VERSION         4
#define BLD_VERSION         0

如何使用bash脚本提取3个单独变量(例如$maj==1$min==4$bld==0)中的值?

我已经尝试过几种围绕此正则表达式的方法:s/\_VERSION\s*(\d*)/使我可以在每行上提取第一个匹配组中的值,但是我找不到理想的解决方案。

例如,这不起作用(并且还需要一个计数器来消除3个值的歧义):

str=$(cat version.h)
for var in ${str[@]}; do
    echo
    if [[ ${var} =~ (\_VERSION\s*)([0-9]*) ]]; then
        echo "match: '${BASH_REMATCH[1]}'"
        echo "match: '${BASH_REMATCH[2]}'"
    fi
done

3 个答案:

答案 0 :(得分:2)

假设您使用bash和GNU sed:

source <(sed -E 's/.*(MAJ|MIN|BLD)_VERSION[[:blank:]]+(.*)/\L\1="\2"/' version.h)

验证变量内容:

$ declare -p maj min bld
declare -- maj="1"
declare -- min="4"
declare -- bld="0"

答案 1 :(得分:1)

这应该做

 maj=$(grep MAJ_VERSION version.h | awk '{print $3}')
 min=$(grep MIN_VERSION version.h | awk '{print $3}')
 bld=$(grep BLD_VERSION version.h | awk '{print $3}')

答案 2 :(得分:0)

如果值在输入文件中始终按该顺序存在:

$ read -r maj min bld < <(awk '{printf "%s ", $3} END{print ""}' file)
$ echo "$maj, $min, $bld"
1, 4, 0

如果您在输入文件中向我们显示的行数多于3行,则将awk调整为:

awk '/^#define.*VERSION/{printf "%s ", $3} END{print ""}' file

如果未预定义订单,则将其再次调整为:

awk '/^#define.*VERSION/{sub(/_.*/,"",$2); f[$2]=$3} END{print f["MAJ"], f["MIN"], f["BLD"]}' file

如果还有其他问题,请告诉...