使用 Awk 使用正则表达式和循环对字段求和

Use Awk to sum a field using regex and loop

Awk 新手和 scripting/programming 并提出问题。希望使用 Awk 对每月系统生成的文本文件(在 Windows10 使用 WSL1)中的字段求和。目标行如下所示:

   Client No.   Client Name                     O/S Balance        Ledger1      Ledger2      Ledger3        Ledger4      Ledger5      Ledger6      Ledger7 Comments
  C00716427.1  Queensview Ohio LLC.              888,924.35           0.00         0.00         0.00     888,924.35     1,803.21         0.00     2,499.96-admin fee
  C00716576.3  0140-8487 Quebec Inc            6,260,987.91           0.00         0.00         0.00   6,260,987.91    18,418.34         0.00        20.99-May 01/20 w/c
  C00716868.1  0328-2400 Quebec Inc.           1,183,948.05           0.00         0.00         0.00   1,183,948.05     2,155.69     5,211.35-1,198,846.32-April 29/20 p/o
  C00617231.3  Ricky Baker Enterprise         49,593,446.91           0.00         0.00         0.00  49,593,446.91    83,220.21   442,202.51-      105.14-May 01/20 w/c
  C00617316.3  101287388 Sarasota LLC.         3,089,599.64           0.00         0.00         0.00   3,089,599.64     2,604.15    27,134.56-        6.08-May 01/20 w/c
  C00617447.2  AmeriUnion Trade 123            6,088,229.78           0.00         0.00         0.00   6,088,229.78    24,921.06         0.00       325.26-surplus funds

我希望输出只有 Client No. 和 Ledger7 的值(不需要 headers)。通过将其他一些解决方案拼凑在一起,这就是我混合在一起的内容:

awk '/C00/ {for(i=1;i<=NF;i++){gsub ( ",","" ); if($i ~ /[0-9]\-[a-zA-Z]/){print substr(,4,8) " " $i} } }' April.txt

产生:

716427.1 2499.96-admin
716576.3 20.99-May
716868.1 5211.35-1198846.32-April
617231.3 105.14-May
617316.3 6.08-May
617447.2 325.26-surplus

仅供参考 - 总有一个“-”分隔 Ledger7 和评论。当 Ledger6 为负值而 Ledger7 >= 100 万美元时,我就会遇到这个问题。

期望输出达到1201803.75的总和:

716427.1 2499.96
716576.3 20.99
716868.1 1198846.32
617231.3 105.14
617316.3 6.08
617447.2 325.26

关于如何改编或重组我的剧本有什么想法吗?让我知道是否需要更多详细信息。 提前致谢。

使用gnu awk,你可以这样做:

awk 'NR>1 {
   amt = gensub(/^.*[-[:blank:]]([0-9][0-9,.]*)-[^-]+$/, "\1", 1)
   gsub(/,/, "", amt)
   print , amt
}' file
C00716427.1 2499.96
C00716576.3 20.99
C00716868.1 1198846.32
C00617231.3 105.14
C00617316.3 6.08
C00617447.2 325.26

工作原理:

  • NR > 1忽略header行
  • gensub 函数匹配并捕获 space 或连字符后跟一个连字符的最后数量文件。
  • gsub 函数删除金额字段中的所有逗号
  • print 简单地打印第 1 列的数量

您能否尝试使用显示的示例进行以下、编写和测试。在 link https://ideone.com/3oYBGq

中编写和测试
awk '
match([=10=],/[-[:blank:]]([0-9][0-9,.]*)-[^-]+$/){
  val=substr([=10=],RSTART,RLENGTH)
  sub(/^ +/,"",val)
  sub(/ +.*$/,"",val)
  num=split(val,arr,"-")
  print ,arr[num-1]
  val=""
}' Input_file

说明: 为以上添加详细说明。

awk '                                                ##Starting awk program from here.
match([=11=],/[-[:blank:]]([0-9][0-9,.]*)-[^-]+$/){      ##Using match function to match regex [-[:blank:]]([0-9][0-9,.]*)-[^-]+ till end of line.
  val=substr([=11=],RSTART,RLENGTH)                      ##Creating val which has substring of matched regex value in current line as shown above.
  sub(/^ +/,"",val)                                  ##Substituting starting space with NULL in val here.
  sub(/ +.*$/,"",val)                                ##Substituting space till everything in last of line in val here.
  num=split(val,arr,"-")                             ##Splitting val value into array arr with delimoter - here.
  print ,arr[num-1]                                ##Printing 1st field and 2nd last value of arr here.
  val=""                                             ##Nullify val here.
}' Input_file                                        ##Mentioning Input_file name here.