2

我在命令行中运行以下命令:

prog1 | prog2

上面的输出(比如X)是一个 4 位十六进制数,例如 FA34。 prog1是一个java程序,每100ms在串口上读取一次数据。prog2cut删除我需要的部分的命令。这工作正常,我可以在标准输出上每 100 毫秒看到一次所需的值。

我想要的是:

prog1 | prog2 | <convert X to decimal> | <multiply by 2>

如何在命令行中一次性使用管道或不使用管道?

注意:我编写了一个 bash 脚本来将 X 转换为十进制并乘以 2。但是我无法将 X 作为参数直接输入到我的脚本中。

4

4 回答 4

3
prog1 | prog2 | xargs -I ^ printf "%d * 2\n" 0x^ | bc

解释:

print 与 %d 将其转换为十进制, bc 进行乘法

于 2012-12-06T13:58:13.117 回答
1

这是一个有趣的可能性:

{ echo "iscale=16"; prog1 | prog2; } | sed 's/$/*2/' | bc

iscale=16首先回显(告诉bc考虑用户在基数 16 中的输入)。然后sed附加*2到每一行,所有这些都通过 bc 转换为十进制并乘以 2。

有一个限制:您的程序prog2必须以大写形式输出所有十六进制数字(例如FA34not fa34)。如果这是一个限制,请使用:

{ echo "iscale=16"; prog1 | prog2; } | sed 's/\(.*\)/\U\1*2/g' | bc

反而。

于 2012-12-06T14:29:14.567 回答
1

要在管道中执行此操作,您可以使用perl

    prog1 | prog2 | perl -ne 'printf ("%d\n",(hex "$_")*2);'

这会遍历 prog2(-n 选项)的 ouptut 行并从 hex ( hex "$_") 重新格式化,并在输出为十进制之前乘以 2。

编辑

您可能需要清除标准输出缓冲区,在 perl 中您可以使用 '$|++' 执行此操作:

 prog1 | prog2 | perl -e '$|++; while(<STDIN>) { chomp; printf ("%d\n",(hex "$_")*2); }'
于 2012-12-06T14:02:18.940 回答
1

这会将 prog2 的输出读取到变量 v,然后将其转换为十进制(使用基本符号16#v)并乘以 2。

prog1 | prog2 | ( read v ; let v=16#$v*2 ; echo $v )

如果流包含多个数字,则将最后一部分更改为

( while read v ; do let v=16#$v*2 ; echo $v ; done )
于 2012-12-06T13:53:44.247 回答