【问题标题】:AWK Script to read from log file从日志文件中读取的 AWK 脚本
【发布时间】:2018-05-22 20:20:00
【问题描述】:

我需要从日志文件中读取某些参数,然后更新到数据库。我正在尝试实现第一部分,即在 shell 脚本中使用 awk 命令从日志文件中读取

日志文件可能包含以下行或更多-

[2018-05-22T11:35:17,857] [RQST: rqst_3ADE-5439-598D-1B8B | TB: 9000042] - [588455375] - INFO - com.test.webapp.services.functions.TestTransactionService - Line 769 - requestType="TESTING",partnerName="Test Merchant 123",testId="123456",lob="TEST1_TO_TEST2",tranType="TEST1",paymentType="P2M",amount="110.00",currency="840",processor="CBN",network="TestSend",responseCode="00", acctNumLastFour="0087",binCountry="USA",binCurr="USD"
[2018-05-22T11:35:17,857] [RQST: rqst_2AEF-2339-598D-1B8B | TB: 9000043] - [588455376] - INFO - com.test.webapp.services.functions.TestTransactionService - Line 770 - requestType="TESTING",partnerName="Test Merchant 234",testId="234567",lob="TEST2_TO_TEST3",tranType="TEST2",paymentType="P2M",amount="120.00",currency="850",processor="CBN",network="TestSend",responseCode="00", acctNumLastFour="0087",binCountry="USA",binCurr="USD"
[2018-05-22T11:35:17,857] [RQST: rqst_4EDA-4539-598D-1B8B | TB: 9000044] - [588455377] - INFO - com.test.webapp.services.functions.TestTransactionService - Line 771 - requestType="TESTING",partnerName="Test Merchant 345",testId="345678",lob="TEST3_TO_TEST4",tranType="TEST3",paymentType="P2M",amount="130.00",currency="860",processor="CBN",network="TestSend",responseCode="00", acctNumLastFour="0087",binCountry="USA",binCurr="USD"

我需要应用过滤器处理器和支付类型,并将金额、货币、网络和响应代码的值检索到将插入到 Oracle 数据库表中的 shell 脚本中的变量。

我是 ShellScript 和 AWK 的新手,无法包装它。我试过使用

awk '/amount/{print}' testAPI.log

但是,返回所有有数量的行。

【问题讨论】:

  • 你的日志真的是这样的吗?不要将其粘贴并格式化为“引用”,而是使用 {} 按钮将其格式化为“代码”(或每行缩进 4 个空格。
  • 您希望该命令做什么? /amount/ 表示如果该行包含该字符串,它应该执行以下块。
  • 如果您只想打印amount="110.00" 之类的内容,则需要将字段分隔符设置为,,然后使用for 循环遍历字段。检查该字段是否匹配/^amount=/,是否打印该字段。
  • @Barmar - 我想从金额(也从问题中提到的其他字段)中检索值 110.00 以更新数据库表
  • 因此,当您到达该字段时,使用split() 将其拆分为" 字符,然后从数组的第二个元素中获取数字。

标签: bash shell awk


【解决方案1】:

由于您没有指定预期的输出,这里有一个模板,您可以根据需要定制

$ awk -F' - ' '{n=split($NF,a,",");
                for(i=1;i<=n;i++) {split(a[i],b,"="); kv[b[1]]=b[2]}}
     kv["processor"]=="\"CBN\"" 
  && kv["paymentType"]=="\"P2M\""{print kv["amount"],kv["currency"]}' file

"110.00" "840"
"120.00" "850"
"130.00" "860"

您也可以修剪双引号,但不确定是否需要它...

【讨论】:

  • 谢谢,它是返回值,但也返回空值,如下所示 - "" "" "" "" "" "" "1.20" "840" "1.20" "840" "1.20 " "840" "1.20" "840" 另外,如何将它们抓取到变量中,以便我可以将它们插入到数据库表中?
  • 表示某些记录缺少变量。您可以read 值并逐条插入记录,但也许获得完整的提取和批量加载会更好(取决于您的数据库/平台/工具)。也许你需要问另一个 Q...
  • 谢谢@karakfa。添加了另一个问题stackoverflow.com/questions/50493142/… 以获取更多详细信息
  • shellscript中如何将kv["amount"]赋值给变量?
  • 该值仅对awk 脚本可见;打印和readbash 脚本中的变量。
【解决方案2】:

我尝试了问题中的三个条目,下面给出了你想要的输出

它检查 $5 是否为 paymentType="P2M" 并且 $8 的值基本上是 processor="CBN",您正在寻找的过滤器,用您需要的过滤器替换。

cat testAccelAPI.log | grep -i "[RQST: rqst" | cut -d ' ' -f 19 | awk -F, '{ if($5=="paymentType=\"P2M\"" && $8=="processor=\"CBN\"") print $5 "=" $6 "="$7 "="$8 "=" $9 "="$10}' | cut -d= -f 4,6,8,9 | tr = " "

【讨论】:

  • 如果可行,我会尝试更新。谢谢@Eby Jacob
  • 确定它在我所做的测试中确实有效,将等待您的更新
  • 如果 paymentType 或 processor 不需要在第 5 或第 8 列,删除 $5 和 $8 也可以吗?
  • 尝试相同的脚本,因为我用行流的空格分隔符进行了剪切,它恰好位于cut之后的第 5 和第 8 列
  • 如果你共享一个合适大小的日志和插入 sql,我可以帮助你构建 sql 以及这个 shell 脚本的输出
猜你喜欢
  • 2013-10-08
  • 2019-07-26
  • 1970-01-01
  • 2021-03-28
  • 2014-12-07
  • 1970-01-01
  • 2020-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多