当数字被引用时,无法弄清楚如何用grep和awk来总结数字

时间:2017-01-13 11:10:10

标签: windows awk grep

我有一个grep命令grep -i "<Project" dottest\report.xml的输出,它给了我这个:

     <Project bdCheckedFiles="8" bdTotalFiles="8" checkedFiles="8" checkedLns="870" name="Common" qfixErrs="0" suppErrs="0" totErrs="228" totFiles="8" totLns="870" />
     <Project bdCheckedFiles="11" bdTotalFiles="11" checkedFiles="11" checkedLns="1440" name="Common.EW" qfixErrs="0" suppErrs="0" totErrs="263" totFiles="11" totLns="1440" />
     <Project bdCheckedFiles="10" bdTotalFiles="10" checkedFiles="10" checkedLns="552" name="Common.EW.Interfaces" qfixErrs="0" suppErrs="0" totErrs="119" totFiles="10" totLns="552" />
     <Project bdCheckedFiles="8" bdTotalFiles="8" checkedFiles="8" checkedLns="2740" name="Common.EW.Messages" qfixErrs="0" suppErrs="0" totErrs="976" totFiles="8" totLns="2740" />
     <Project bdCheckedFiles="6" bdTotalFiles="6" checkedFiles="6" checkedLns="2152" name="DataModel" qfixErrs="0" suppErrs="0" totErrs="922" totFiles="6" totLns="2152" />
     <Project bdCheckedFiles="5" bdTotalFiles="5" checkedFiles="5" checkedLns="745" name="ExternalMessages" qfixErrs="0" suppErrs="0" totErrs="507" totFiles="5" totLns="745" />
     <Project bdCheckedFiles="0" bdTotalFiles="0" checkedFiles="0" checkedLns="0" name="Resources" qfixErrs="0" suppErrs="0" totErrs="0" totFiles="7" totLns="996" />
     <Project bdCheckedFiles="3" bdTotalFiles="3" checkedFiles="3" checkedLns="725" name="ScriptReader" qfixErrs="0" suppErrs="0" totErrs="373" totFiles="3" totLns="725" />
     <Project bdCheckedFiles="7" bdTotalFiles="7" checkedFiles="7" checkedLns="1812" name="TestController" qfixErrs="0" suppErrs="0" totErrs="594" totFiles="7" totLns="1812" />
     <Project bdCheckedFiles="10" bdTotalFiles="10" checkedFiles="10" checkedLns="1232" name="TestControllerCli" qfixErrs="0" suppErrs="0" totErrs="88" totFiles="10" totLns="1232" />
     <Project bdCheckedFiles="16" bdTotalFiles="16" checkedFiles="16" checkedLns="1742" name="TestControllerGui" qfixErrs="0" suppErrs="0" totErrs="125" totFiles="16" totLns="1742" />
     <Project bdCheckedFiles="2" bdTotalFiles="2" checkedFiles="2" checkedLns="790" name="UnitTest_Common" qfixErrs="0" suppErrs="0" totErrs="162" totFiles="2" totLns="790" />
     <Project bdCheckedFiles="4" bdTotalFiles="4" checkedFiles="4" checkedLns="1629" name="UnitTest_DataModel" qfixErrs="0" suppErrs="0" totErrs="586" totFiles="4" totLns="1629" />
     <Project bdCheckedFiles="2" bdTotalFiles="2" checkedFiles="2" checkedLns="1479" name="UnitTest_ExternalMessages" qfixErrs="0" suppErrs="0" totErrs="591" totFiles="2" totLns="1479" />
     <Project bdCheckedFiles="9" bdTotalFiles="9" checkedFiles="9" checkedLns="1117" name="UnitTest_ScriptReader" qfixErrs="0" suppErrs="0" totErrs="29" totFiles="9" totLns="1117" />
     <Project bdCheckedFiles="9" bdTotalFiles="9" checkedFiles="9" checkedLns="1509" name="UnitTest_TestController" qfixErrs="0" suppErrs="0" totErrs="144" totFiles="9" totLns="1509" />

现在我想添加一些列

我有以下bash代码可以执行此操作(给定列号 - 在本例中为3)。但它仅在列是单个整数时才有效。在我的grep命令的输出中,我得到引号内的数字,所以我不能再使用它了。我不知道如何提取它。

这是我目前的bash代码:

grep  -i "<Project" dottest\report.xml | awk '{ SUM += $3; print $3 } END { print SUM }'

这会产生:

bdTotalFiles="8"
bdTotalFiles="11"
bdTotalFiles="10"
bdTotalFiles="8"
bdTotalFiles="6"
bdTotalFiles="5"
bdTotalFiles="0"
bdTotalFiles="3"
bdTotalFiles="7"
bdTotalFiles="10"
bdTotalFiles="16"
bdTotalFiles="2"
bdTotalFiles="4"
bdTotalFiles="2"
bdTotalFiles="9"
bdTotalFiles="9"
0   (this is the sum)

所以我想要的是总结所有的bdCheckedFiles或totErrs(例如)。

我尝试在其中添加tr来替换引号:

D:\workspace > grep  -i "<Project" dottest\report.xml | tr '"' ' ' | awk '{ SUM += $3; print $3 } END { print SUM }'
tr: extra operand '|'
Try 'tr --help' for more information.
grep: write error: Invalid or incomplete multibyte or wide character

然而,如果我删除awk部分它看起来没问题,所以我无法看到问题:(

D:\workspace > grep  -i "<Project" dottest\report.xml | tr '"' ' '
  <ProjectInformations>
  <Projects>
     <Project bdCheckedFiles= 8  bdTotalFiles= 8  checkedFiles= 8  checkedLns= 870  name= Common  qfixErrs= 0  suppErrs= 0  totErrs= 228  totFiles= 8  totLns= 870  />
     <Project bdCheckedFiles= 11  bdTotalFiles= 11  checkedFiles= 11  checkedLns= 1440  name= Common.EW  qfixErrs= 0  suppErrs= 0  totErrs= 263  totFiles= 11  totLns= 1440  />
     <Project bdCheckedFiles= 10  bdTotalFiles= 10  checkedFiles= 10  checkedLns= 552  name= Common.EW.Interfaces  qfixErrs= 0  suppErrs= 0  totErrs= 119  totFiles= 10  totLns= 552  />
     <Project bdCheckedFiles= 8  bdTotalFiles= 8  checkedFiles= 8  checkedLns= 2740  name= Common.EW.Messages  qfixErrs= 0  suppErrs= 0  totErrs= 976  totFiles= 8  totLns= 2740  />
     <Project bdCheckedFiles= 6  bdTotalFiles= 6  checkedFiles= 6  checkedLns= 2152  name= DataModel  qfixErrs= 0  suppErrs= 0  totErrs= 922  totFiles= 6  totLns= 2152  />
     <Project bdCheckedFiles= 5  bdTotalFiles= 5  checkedFiles= 5  checkedLns= 745  name= ExternalMessages  qfixErrs= 0  suppErrs= 0  totErrs= 507  totFiles= 5  totLns= 745  />
     <Project bdCheckedFiles= 0  bdTotalFiles= 0  checkedFiles= 0  checkedLns= 0  name= Resources  qfixErrs= 0  suppErrs= 0  totErrs= 0  totFiles= 7  totLns= 996  />
     <Project bdCheckedFiles= 3  bdTotalFiles= 3  checkedFiles= 3  checkedLns= 725  name= ScriptReader  qfixErrs= 0  suppErrs= 0  totErrs= 373  totFiles= 3  totLns= 725  />
     <Project bdCheckedFiles= 7  bdTotalFiles= 7  checkedFiles= 7  checkedLns= 1812  name= TestController  qfixErrs= 0  suppErrs= 0  totErrs= 594  totFiles= 7  totLns= 1812  />
     <Project bdCheckedFiles= 10  bdTotalFiles= 10  checkedFiles= 10  checkedLns= 1232  name= TestControllerCli  qfixErrs= 0  suppErrs= 0  totErrs= 88  totFiles= 10  totLns= 1232  />
     <Project bdCheckedFiles= 16  bdTotalFiles= 16  checkedFiles= 16  checkedLns= 1742  name= TestControllerGui  qfixErrs= 0  suppErrs= 0  totErrs= 125  totFiles= 16  totLns= 1742  />
     <Project bdCheckedFiles= 2  bdTotalFiles= 2  checkedFiles= 2  checkedLns= 790  name= UnitTest_Common  qfixErrs= 0  suppErrs= 0  totErrs= 162  totFiles= 2  totLns= 790  />
     <Project bdCheckedFiles= 4  bdTotalFiles= 4  checkedFiles= 4  checkedLns= 1629  name= UnitTest_DataModel  qfixErrs= 0  suppErrs= 0  totErrs= 586  totFiles= 4  totLns= 1629  />
     <Project bdCheckedFiles= 2  bdTotalFiles= 2  checkedFiles= 2  checkedLns= 1479  name= UnitTest_ExternalMessages  qfixErrs= 0  suppErrs= 0  totErrs= 591  totFiles= 2  totLns= 1479  />
     <Project bdCheckedFiles= 9  bdTotalFiles= 9  checkedFiles= 9  checkedLns= 1117  name= UnitTest_ScriptReader  qfixErrs= 0  suppErrs= 0  totErrs= 29  totFiles= 9  totLns= 1117  />
     <Project bdCheckedFiles= 9  bdTotalFiles= 9  checkedFiles= 9  checkedLns= 1509  name= UnitTest_TestController  qfixErrs= 0  suppErrs= 0  totErrs= 144  totFiles= 9  totLns= 1509  />

3 个答案:

答案 0 :(得分:1)

理想情况下,您应该使用xml解析器来处理此类事情。

以下是脆弱的解决方案,如果字段的顺序发生变化,则无法解决,但您可以使用引号"作为awk -F \"的字段分隔符,而不是默认的空格并检索正确的值:

grep  -i "<Project" dottest\report.xml | awk -F \" '{ SUM += $4; print $3$4 } END { print SUM }'

输出:

 bdTotalFiles=8
 bdTotalFiles=11
 bdTotalFiles=10
 bdTotalFiles=8
 bdTotalFiles=6
 bdTotalFiles=5
 bdTotalFiles=0
 bdTotalFiles=3
 bdTotalFiles=7
 bdTotalFiles=10
 bdTotalFiles=16
 bdTotalFiles=2
 bdTotalFiles=4
 bdTotalFiles=2
 bdTotalFiles=9
 bdTotalFiles=9
110

答案 1 :(得分:1)

为什么要运行grep和awk?

awk '/Projects/ { n=match($0, /bdTotalFiles="([[:digit:]]+)"/, r); sum +=r[1]; } END { print sum; }'

这只会运行awk。如果行中有字符串Projects,则进行求和,然后在bdTotalFiles = string之后找到数字。如果您的报价是可选的,您可以放一个?在“s之后进入正则表达式。并且很容易扩展到多列。未经测试。

答案 2 :(得分:1)

单线

awk 'match($0, /bdTotalFiles="[0-9]+"/){s=substr($0,RSTART,RLENGTH); print s; gsub(/[^0-9]+/,"",s); total+=s}END{print "Sum",total}' file

<强>解释

awk '
  match($0, /bdTotalFiles="[0-9]+"/){      # Search for match (bdTotalFiles="[0-9]+")  in current record/row ($0), if found do things inside braces
              s=substr($0,RSTART,RLENGTH)  # extract matched part from current record ($0) and assign to variable s
              print s                      # print extracted contents (contents of variable s) 
              gsub(/[^0-9]+/,"",s)         # extract only numbers, remove anything except numeric values from extracted contents of variable s
              total+=s                     # sum up values
   }
   END{
     print "Sum",total                     # finally print sum
   }
   ' file                                  # Input file

<强>输入

$ cat f
  <Project bdCheckedFiles="8" bdTotalFiles="8" checkedFiles="8" checkedLns="870" name="Common" qfixErrs="0" suppErrs="0" totErrs="228" totFiles="8" totLns="870" />
     <Project bdCheckedFiles="11" bdTotalFiles="11" checkedFiles="11" checkedLns="1440" name="Common.EW" qfixErrs="0" suppErrs="0" totErrs="263" totFiles="11" totLns="1440" />
     <Project bdCheckedFiles="10" bdTotalFiles="10" checkedFiles="10" checkedLns="552" name="Common.EW.Interfaces" qfixErrs="0" suppErrs="0" totErrs="119" totFiles="10" totLns="552" />
     <Project bdCheckedFiles="8" bdTotalFiles="8" checkedFiles="8" checkedLns="2740" name="Common.EW.Messages" qfixErrs="0" suppErrs="0" totErrs="976" totFiles="8" totLns="2740" />
     <Project bdCheckedFiles="6" bdTotalFiles="6" checkedFiles="6" checkedLns="2152" name="DataModel" qfixErrs="0" suppErrs="0" totErrs="922" totFiles="6" totLns="2152" />
     <Project bdCheckedFiles="5" bdTotalFiles="5" checkedFiles="5" checkedLns="745" name="ExternalMessages" qfixErrs="0" suppErrs="0" totErrs="507" totFiles="5" totLns="745" />
     <Project bdCheckedFiles="0" bdTotalFiles="0" checkedFiles="0" checkedLns="0" name="Resources" qfixErrs="0" suppErrs="0" totErrs="0" totFiles="7" totLns="996" />
     <Project bdCheckedFiles="3" bdTotalFiles="3" checkedFiles="3" checkedLns="725" name="ScriptReader" qfixErrs="0" suppErrs="0" totErrs="373" totFiles="3" totLns="725" />
     <Project bdCheckedFiles="7" bdTotalFiles="7" checkedFiles="7" checkedLns="1812" name="TestController" qfixErrs="0" suppErrs="0" totErrs="594" totFiles="7" totLns="1812" />
     <Project bdCheckedFiles="10" bdTotalFiles="10" checkedFiles="10" checkedLns="1232" name="TestControllerCli" qfixErrs="0" suppErrs="0" totErrs="88" totFiles="10" totLns="1232" />
     <Project bdCheckedFiles="16" bdTotalFiles="16" checkedFiles="16" checkedLns="1742" name="TestControllerGui" qfixErrs="0" suppErrs="0" totErrs="125" totFiles="16" totLns="1742" />
     <Project bdCheckedFiles="2" bdTotalFiles="2" checkedFiles="2" checkedLns="790" name="UnitTest_Common" qfixErrs="0" suppErrs="0" totErrs="162" totFiles="2" totLns="790" />
     <Project bdCheckedFiles="4" bdTotalFiles="4" checkedFiles="4" checkedLns="1629" name="UnitTest_DataModel" qfixErrs="0" suppErrs="0" totErrs="586" totFiles="4" totLns="1629" />
     <Project bdCheckedFiles="2" bdTotalFiles="2" checkedFiles="2" checkedLns="1479" name="UnitTest_ExternalMessages" qfixErrs="0" suppErrs="0" totErrs="591" totFiles="2" totLns="1479" />
     <Project bdCheckedFiles="9" bdTotalFiles="9" checkedFiles="9" checkedLns="1117" name="UnitTest_ScriptReader" qfixErrs="0" suppErrs="0" totErrs="29" totFiles="9" totLns="1117" />
     <Project bdCheckedFiles="9" bdTotalFiles="9" checkedFiles="9" checkedLns="1509" name="UnitTest_TestController" qfixErrs="0" suppErrs="0" totErrs="144" totFiles="9" totLns="1509" />

<强>输出

$ awk 'match($0, /bdTotalFiles="[0-9]+"/){s=substr($0,RSTART,RLENGTH); print s; gsub(/[^0-9]+/,"",s); total+=s}END{print "Sum",total}' f
bdTotalFiles="8"
bdTotalFiles="11"
bdTotalFiles="10"
bdTotalFiles="8"
bdTotalFiles="6"
bdTotalFiles="5"
bdTotalFiles="0"
bdTotalFiles="3"
bdTotalFiles="7"
bdTotalFiles="10"
bdTotalFiles="16"
bdTotalFiles="2"
bdTotalFiles="4"
bdTotalFiles="2"
bdTotalFiles="9"
bdTotalFiles="9"
Sum 110