添加数字而不使用grep -c选项

时间:2014-08-06 19:23:50

标签: bash command-line

我有一个像

这样的txt文件
Peugeot:406:1999:Silver:1
Ford:Fiesta:1995:Red:2
Peugeot:206:2000:Black:1
Ford:Fiesta:1995:Red:2

我正在寻找一个可以计算红色福特嘉年华汽车数量的命令。 每行中的最后一个数字是特定汽车的数量。 我正在寻找的命令不能使用grep的

所以这个命令应该输出数字4。

欢迎任何帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

一小段awk可以解决这个问题:

awk -F: '$1=="Ford" && $4=="Red" { c+=$5 } END { print c }' file

输出:

4

说明:

-F:开关表示输入字段分隔符为冒号,因此汽车制造商为$1(第1个字段),模型为$2等。

如果第一场是"福特"并且第4个字段是" Red",然后将第5个(最后一个)字段的值添加到变量c。处理完整个文件后,打印出c

的值

对于本机bash解决方案:

c=0
while IFS=":" read -ra col; do 
    [[ ${col[0]} == Ford ]] && [[ ${col[3]} == Red ]] && (( c += col[4] ))
done < file && echo $c

有效地应用与上面的awk相同的逻辑,没有任何其他依赖。

答案 1 :(得分:1)

方法:

1。)使用一些脚本语言进行计数,例如awkperl等。 Awk解决方案已经发布,这是一个perl解决方案。

perl -F: -lane '$s+=$F[4] if m/Ford:.*:Red/}{print $s' < carfile
#or
perl -F: -lane '$s+=$F[4] if ($F[0]=~m/Ford/ && $F[3]=~/Red/)}{print $s' < carfile

两个例子都打印

4

2.)第二种方法基于shell-pipelinelining

  • 过滤掉右侧行
  • 使用计数
  • 提取列
  • 数字总和

例如一些例子:

grep 'Ford:.*:Red:' carfile | cut -d: -f5 | paste -sd+ | bc
  • grep过滤掉右侧行
  • cut获取最后一列
  • paste会创建一个类似2+2的行,
  • 可以计算什么
  • 用于计算的bc

另一个例子:

sed -n 's/\(Ford:.*:Red\):\(.*\)/\2/p' carfile | paste -sd+ | bc
  • sed过滤器和提取

另一个例子 - 不同的计算方式

(echo 0 ; sed -n 's/\(Ford:.*:Red\):\(.*\)/\2+/p' carfile ;echo p )| dc
  • 数字由名为dc的RPN计算器计算,例如它像0 2 +一样工作 - 首先是值,最后是操作。
  • 第一个echo放入堆栈0
  • sed会创建一个数字流,例如2+ 2+
  • 最后一个echo p打印堆栈

存在许多其他可能性如何计算数字的数量。

例如按bash

计算
while read -r num
do
   sum=$(( $sum + $num ))
done < <(sed -n 's/\(Ford:.*:Red\):\(.*\)/\2/p' carfile)

和纯粹的bash:

while IFS=: read -r maker model year color count
do
    if [[ "$maker" == "Ford" && "$color" == "Red" ]]
    then
        (( sum += $count ))
    fi
done < carfile
echo $sum