parsing - 使用 awk 检查一行中的多个位置的数据
问题描述
我正在尝试提取一些最初来自大型机的信息。这些行都是 ASCII 字符数据,但每一行都被认为是多段的,因此具有不同的行长。字段是长度分隔的。行中有一个字段指示变量部分预期有多少行段。我想做的是在这些变量段中寻找指标的存在,并从中提取一些数据。
一个简化的例子如下所示;
UUID12345 1 ABC 1 345
UUID23456 2 XYZ 4 763 ABC 4 678
UUID34567 3 XYZ 4 763 ABC 2 456 QRS 2 456
UUID45678 2 DEF 1 345 TUV 8 111
UUID56789 0
第二列指示预期有多少段。最多可以有99个段,但实际上少于 10 个。在上面的示例中,每个段将包含 10 个字节,例如从第一行的 ABC 位置开始。我要提取的是每行的第一列以及包含 ABC 的任何段的最后 3 个字符的值。
因此,上述行的示例输出可能是;
UUID12345 345
UUID23456 678
UUID34567 456
UUID45678
UUID56789
我知道一些非常基本的 awk,并且可以查找一行的特定部分,但不知道如何实现我需要的。例如,以下为我提供了提取第一行的能力,但只能通过查看特定位置,并且没有考虑指示可变段数的第二列。
awk '{ if (substr($0, 0, 4)=="UUID" && substr($0, 15, 3)=="ABC") {print substr($0, 0, 9) " " substr ($0, 21,3)}}' <<< "UUID12345 1 ABC 1 345"
编辑
根据我在下面对 Ed Morton 的评论,这就是我最终得到的对我有用的东西(其中 test.txt 是上面显示的示例);
awk '{segs=substr($0, 11, 1); acc=substr($0, 1, 10); startCol=15; val=""; for(i=startCol; i<startCol+(10 * segs); i+= 10) if (substr($0, i, 3)=="ABC") val=substr($0, i + 6, 3); print acc " " segs " " val}' test.txt
解决方案
$ awk '{val=""; for (i=3; i<NF; i+=3) if ($i=="ABC") val=$(i+2); print $1, val}' file
UUID12345 345
UUID23456 678
UUID34567 456
UUID45678
UUID56789
如果这还不是您所需要的,那么编辑您的问题以提供更具代表性的示例输入/输出,从而更好地满足您的所有要求。
推荐阅读
- reactjs - `Component` 的 React 和 Typescript 组件道具类型
- azure - Web hook 调用后 Azure Logic APP 恢复工作流程
- javascript - 使用 Javascript 获取表中除第一个之外的所有第一个值
- java - 如何更改其他活动的共享偏好值?
- gitpython - 如何在 gitpython 中使用 git log --oneline
- python - 为什么使用命令 to_csv() 删除某些数据
- asp.net-mvc - 如何删除或禁用 ipad safari 中的地址栏?
- javascript - Vue.JS - “历史”和“抽象”路由器?
- ios - 为什么我的应用程序不显示要求访问用户位置的警报?
- jakarta-ee - 链接到官方 JavaEE 8 API 文档