使用管道输出

时间:2017-02-18 07:27:46

标签: bash unix

所以我正在运行一个可以接收几个未显示的参数($ 1和$ 2)的随机文件,然后对传递的参数执行某些操作...

使用第三个参数,我应该在file1中搜索$ 3(或不是$ 3)并将此实例的数量添加到file2 ...

这很好用:

cat file1 | grep $3 | wc -l | while read line1; do echo $3 $line1 > file2; done

cat file1 | grep -v $3 | wc -l | while read line2; do echo not $3 $line2 >> file2; done

现在我正在尝试读取持有搜索实例的file2,我想获取文件中的数字,得到总和,然后追加到file2。所以,例如,如果3美元是"宝贝":

file2将包含 -

baby 30
not baby 20

然后我想得到20和30的总和并附加到同一个文件2,所以它看起来像 -

baby 30
not baby 20
total 50

这就是我现在所拥有的:

cat file2 | grep -o '[0-9]*' | while read num ; do sum=$(($sum + $num));echo "total $sum" >> file2; done

我的文件2最终有两行总计,其中一行是我需要的 -

baby 30
not baby 20
total 30
total 50

我在这里想念的是什么?

2 个答案:

答案 0 :(得分:1)

这种情况正在发生,因为你的回声在你的for循环中。

显而易见的解决方案是将其移到for循环之外,但是如果你尝试这个,你会发现$ sum没有设置,这是因为while循环和管道实际上是作为自己的进程生成的。您可以使用大括号({})对命令进行分组来解决此问题:

cat file2 | grep -o '[0-9]*' | { while read num ; do sum=$(($sum + $num)); done; echo "total $sum" >> file2; }

其他答案确实指出了更好的方法,但这有助于您了解正在发生的事情。

答案 1 :(得分:0)

  

cat file1 | grep $ 3 | wc -l |读取line1;做echo $ 3 $ line1>文件2;完成

如果要计算$ 3的实例,可以使用grep的-c选项,避免使用wc(1)的管道。而且,引用3美元会更好。最后,您不需要循环来读取计数(来自wc或grep):它是一行!所以,上面的代码可以写成:

count=$(grep -c "$3" file1)
echo $count $3 >file2

第二个grep与以前一样:

count=$(grep -vc "$3" file1)
echo $count $3 >>file2

现在你应该得到中间结果:

  30宝宝   20不是宝贝

请注意,我颠倒了两个术语,计数和模式;这是因为我们知道计数是一个单词,但模式可能是更多的单词。因此,首先编写计数,我们有一个明确定义的格式:“计数,然后所有其余的”。

第三个循环可以这样写:

while read num string; do 
  # string is filled with all the rest on the line
  let "sum = $sum + $num"
done < file2
echo "$sum total" >> file2

还有其他方法来总结总数;如果需要,您也可以再次反转最终文件的条款,就像您的原始条款一样 - 可以通过再次使用另一个文件来完成。