Shell 如何提取此自定义程序的ppl?

Shell 如何提取此自定义程序的ppl?,shell,unix,Shell,Unix,我有一个程序,当我运行时,它会在命令行中打印如下内容: file test.test: 427 sentences, 2433 words, 1186 OOVs 0 zeroprobs, logprob= -4914.55 ppl= 862.603 ppl1= 8731.65 但是我只想把862.603保存在一个环境变量中。如何从程序的输出中提取该单个数字?$MY_ENV_VAR=$myprogram | grep'ppl=''sed-r's:^.*ppl=[0-9\.]+.*::\1:'$M

我有一个程序,当我运行时,它会在命令行中打印如下内容:

file test.test: 427 sentences, 2433 words, 1186 OOVs
0 zeroprobs, logprob= -4914.55 ppl= 862.603 ppl1= 8731.65
但是我只想把862.603保存在一个环境变量中。如何从程序的输出中提取该单个数字?

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

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

您可以使用fgrep>只获取您想要的行,并且只获取数字:

program | fgrep ppl= | awk '{ print $6 }'
您可以使用fgrep仅获取所需线路,使用awk仅获取所需号码:

program | fgrep ppl= | awk '{ print $6 }'
试试这个:

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

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

到目前为止,我看到的每一个答案都有一些不足之处,因此我想我将继续并将其添加到组合中:

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

我更喜欢使用grep的perl扩展名-p:

o标志告诉grep只打印匹配的字符串,在本例中,该字符串就是您要查找的数字

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

我更喜欢这种解决方案,因为您实际上希望搜索特定的字符串,而grep擅长于此。唯一的问题是,您还需要执行lookback,这仅在perl正则表达式扩展中受支持

因此,如果您的grep不支持perl regex扩展,我将使用sed:

var=$(myProgram | sed 's/ppl=\s*\(\d\+\.\d\+\)/\1/')
这假设gnu是sed,这是很常见的。如果您没有使用gnu,请使用以下方法:

var=$(myProgram | sed 's/ppl=[ \t]*\([0-9]\{1,\}\.[0-9]\{1,\})/\1/')
这里的底线是,完成此任务绝对不需要多个管道。打开管道意味着开始新的过程,这是昂贵的。通常,在shell中编码时,您希望打开尽可能少的管道来完成任务

编辑


只是要指出:如果您有可用的perl扩展,sputnick的答案现在几乎正是您想要的。他和我现在唯一的区别是一个小小的正则表达式更改,你可能最终不得不调整自己以满足你的需要。

到目前为止,我看到的每个答案都有一些不足之处,所以我想我会继续添加以下内容:

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

我更喜欢使用grep的perl扩展名-p:

o标志告诉grep只打印匹配的字符串,在本例中,该字符串就是您要查找的数字

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

我更喜欢这种解决方案,因为您实际上希望搜索特定的字符串,而grep擅长于此。唯一的问题是,您还需要执行lookback,这仅在perl正则表达式扩展中受支持

因此,如果您的grep不支持perl regex扩展,我将使用sed:

var=$(myProgram | sed 's/ppl=\s*\(\d\+\.\d\+\)/\1/')
这假设gnu是sed,这是很常见的。如果您没有使用gnu,请使用以下方法:

var=$(myProgram | sed 's/ppl=[ \t]*\([0-9]\{1,\}\.[0-9]\{1,\})/\1/')
这里的底线是,完成此任务绝对不需要多个管道。打开管道意味着开始新的过程,这是昂贵的。通常,在shell中编码时,您希望打开尽可能少的管道来完成任务

编辑


只是要指出:如果您有可用的perl扩展,sputnick的答案现在几乎正是您想要的。他和我现在唯一的区别是一个小小的正则表达式更改,您可能需要调整自己,以满足最终的需要。

除了保留数字之外,它还保留了许多其他输出。@lanzz我的错,我没有注意到多行。修正!:@威廉·珀塞尔——为什么?我经常这样做。@williampersell为什么不将grep传输到sed?sed可以像grep一样进行过滤。grep模式| sed s/foo/bar与sed-n'/pattern/s/foo/bar/p或sed-e/pattern/相同!d-e s/foo/bar/。与其通过使用grep进行预处理来加倍IO,不如使用sed进行过滤。除了数字之外,它还保留了很多其他输出。@lanzz我的错,我没有注意到多行。修正!:@威廉·珀塞尔——为什么?我经常这样做。@williampersell为什么不将grep传输到sed?sed可以像grep一样进行过滤。grep模式| sed s/foo/bar与sed-n'/pattern/s/foo/bar/p或sed-e/pattern/相同!d-e s/foo/bar/。与其通过使用grep进行预处理来加倍IO,不如使用sed进行过滤。我非常肯定任何一种awk都可以工作,而且我也非常肯定任何解决方案都需要安装某些实用程序。不需要grep | awk,它是无用的:program | awk'/ppl=/{print$6}我非常肯定任何一种awk都可以工作,而且我也非常确定任何解决方案都需要安装某些实用程序。这里不需要grep | awk,它是无用的:程序| awk'/ppl=/{print$6}'+1,现在它从管道读取。我会的
我刚刚直接评论了你的答案,但是没有人提出简单的sed解决方案,所以我决定发布我自己的答案。但是,正如我所说,如果grep-P是可用的,这是我的首选解决方案。我会直接评论你的答案,但是没有人提出简单的sed解决方案,所以我决定发布我自己的答案。但是,正如我所说,如果grep-P可用,这是我的首选解决方案。如果它确实是您自己的程序,请添加一个选项,以机器可读的格式生成输出,即仅数字、变量=值、JSON或抖动XML。这是什么程序?它能够将其输出到文件中吗?如果它确实是您自己的程序,请添加一个选项以机器可读的格式生成输出,即仅输出数字、变量=值、JSON或抖动XML。这是什么程序?它能把它输出到一个文件吗?