BASH:如何对管道中的数字进行算术运算

时间:2010-07-17 16:01:27

标签: linux bash unix shell math

我在管道中获得了一个数字流,并希望在将它们传递到下一部分之前执行一些操作,但是我有点迷失在不破坏管道的情况下如何处理它。 / p>

例如

> echo "1 2 3 4 5" | some command | cat 
1 4 9 16 25
>

你对如何制作这样的作品有什么想法吗?我想要执行的实际操作只是为每个数字添加一个。

10 个答案:

答案 0 :(得分:7)

echo 1 2 3 4 5|{
  read line; 
  for i in $line;
  do
    echo -n "$((i * i)) "; 
  done; 
  echo
}

{}创建分组。您可以为此创建一个脚本。

答案 1 :(得分:4)

我写道:

echo "1 2 3 4 5" | {
  for N in $(cat); do
    echo $((N ** 2))
  done | xargs
}

我们可以将其视为“地图”(功能编程)。有很多方法可以在bash中编写“map”函数(使用stdin,function args,...),例如:

map_stdin() {
  local FUNCTION=$1
  while read LINE; do
    $FUNCTION $LINE
  done
}

square() { echo "$(($1 * $1))"; }

$ echo "1 2 3 4 5" | xargs -n1 | map_stdin square | xargs
1 4 9 16 25

答案 2 :(得分:3)

或..

echo "1 2 3 4 5" | xargs -n 1 | while read number 
 do
   echo $((number * number))
 done

答案 3 :(得分:3)

echo 1 2 3 4 5 | xargs -n 1 expr -1 +

答案 4 :(得分:1)

或者您可以将表达式传递给bc:

echo "1 2 3 4 5" | (
  read line; 
  for i in $line;
  do
    echo $i^2 | bc; 
  done; 
  echo
)

答案 5 :(得分:1)

echo 1 2 3 4 5 | xargs -n 1 bash -c 'echo $(($1*$1))' args 

答案 6 :(得分:1)

使用awk是另一个非常紧凑的解决方案

echo "1 2 3 4 5" | xargs -n1 | awk '{print $1**2}' | xargs

答案 7 :(得分:0)

如果您更喜欢Python:

#!/bin/python
num = input()
while num:
    print(int(num) + 1) # Whatever manipulation you want
    try:
        num = input()
    except EOFError:
        break

答案 8 :(得分:0)

xargs,xargs,xargs

echo 1 2 3 4 5 | xargs -n1 echo | xargs -I NUMBER expr NUMBER \* NUMBER | xargs

或者,并行:

squareit () { expr $1 \* $1; }
export -f squareit
echo 1 2 3 4 5 | xargs -n1 | parallel --gnu squareit | xargs

如果您将管道作为一组标准的args传递,那么这将更简单:

parallel --gnu "expr {} \* {}" ::: $(echo 1 2 3 4 5) | xargs

甚至:

parallel --gnu "expr {} \* {}" ::: 1 2 3 4 5 | xargs

非常值得一看文档中的示例:https://www.gnu.org/software/parallel/man.html

答案 9 :(得分:-1)

你可能喜欢这样的东西:

echo "1 2 3 4 5" | perl -ne 'print $_ ** 2, " " for split / /, $_'

甚至是这样:

echo "1 2 3 4 5" | perl -ne 'print join " ", map {$_ ** 2} split / /, $_'