如何使用shell从linux程序的输出中提取单个数字?

时间:2012-06-03 19:53:24

标签: shell unix

我有一个程序,当我运行时,它在命令行中输出这样的东西:

file test.test: 427 sentences, 2433 words, 1186 OOVs
0 zeroprobs, logprob= -4914.55 ppl= 862.603 ppl1= 8731.65

但我只想在环境变量中保存数字862.603。如何从程序输出中提取该单个数字?

5 个答案:

答案 0 :(得分:3)

到目前为止我看到的每个答案都有一些不足之处,所以我想我会继续把这个添加到混音中:

有几种方法可以做到这一点。

我首选的方法是使用grep的perl扩展名(-P):

var=$(myProgram | grep -oP 'ppl=\s*\K\d+\.\d+')

-o标志告诉grep只打印匹配的字符串,在这种情况下是您要查找的数字。

请注意,这与(几乎)与sputnick的解决方案完全相同,但我已将其改编为直接通过管道而不是文件从您的程序中读取。

我更喜欢这个解决方案,因为你基本上想要搜索grep擅长的特定字符串。唯一的问题是你也想做一个lookbehind,它只在perl regex扩展中支持。

所以,如果你的grep不支持perl regex扩展,我会使用sed:

var=$(myProgram | sed 's/ppl=\s*\(\d\+\.\d\+\)/\1/')

这假设gnu sed,这很常见。如果你没有gnu sed,那就用这个:

var=$(myProgram | sed 's/ppl=[ \t]*\([0-9]\{1,\}\.[0-9]\{1,\})/\1/')

这里的底线是,您绝对需要 需要多个管道才能完成此任务。打开管道意味着开始新的流程,这是昂贵的。通常,在shell中进行编码时,您需要打开尽可能少的管道来完成任务。


修改

只是指出来:如果你有可用的perl扩展名,那么现在几乎就是你想要的答案。他和我现在唯一的区别就是一个小的正则表达式改变(你可能不得不调整自己以适应你最终的需要)。

答案 1 :(得分:2)

$ var=$(<YOUR_COMMAND> | grep -oP "ppl= \K\d+\.\d+")
$ echo $var
862.603

如果您的发行版缺少grep -P选项,则应安装pcregrep

编辑:发布后编辑以更好地满足您的需求:我在文件上使用grep,现在这是您的命令。

Edit2 :这是一种awk方式:

var=$(
    <YOUR_COMMAND> |
        awk '
            /ppl=/{
                for (i=0; i<NF; i++) {
                    if ($(i) ~ "ppl=" && $(i) > 1) {
                        print $(i+1)
                    }
                }
            }'
        )
echo $var

答案 2 :(得分:0)

$ MY_ENV_VAR="$(myprogram |grep 'ppl= '|sed -r 's:^.*ppl= ([0-9\.]+).*:\1:')“

答案 3 :(得分:0)

您可以使用fgrep来获取所需的行,而awk只能获得您想要的数字:

program | fgrep ppl= | awk '{ print $6 }'

答案 4 :(得分:0)

试试这个:

var=`./program | grep 'ppl=' | cut -d= -f3 | sed 's/ //g' | sed 's/ppl1//g'`