【问题标题】:Parse input text that is located using left padding spaces解析使用左侧填充空格定位的输入文本
【发布时间】:2019-12-10 10:45:43
【问题描述】:

我有以下文本结构。 JTT JNX JNA JNO 下面的值属于上一行。

9   8    11  56507785                                     93
         JTT  JNX  JNA  JNO
          76        98

9   8    60  3269557                                      58
9   8    53  7269558                                     150
         JTT  JNX  JNA  JNO
         132   71       45-7705678

9   8    62  439559                                       82

我想解析它以便在一行中打印相应的值,如下所示:

H1    H2    H3    H4           H5    JTT  JNX  JNA  JNO
9     8     11    56507785     93     76        98
9     8     60    3269557      58    
9     8     53    7269558     150    132   71       45-7705678
9     8     62    439559       82    

我的问题是,当我将 awk 与 FS = 空间(默认 FS)一起使用时,它将 JTT 作为第一个字段,而 JTT 之前有 9 个空格,所以我认为应该使用一些技术来计算从左边到@ 987654324@ 并计算从开始到低于JTT JNX JNA JNO 的值的空格数,以便正确定位每个值。我的意思是,76 和 132 低于 JTT 标头,971 低于 JNX,98 低于 JNA 和 45-7705678 低于 JNO。

如何在 awk 中做到这一点?

$ awk --version
GNU Awk 5.0.0, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.1.2)
Copyright (C) 1989, 1991-2019 Free Software Foundation.

$ uname -srv
CYGWIN_NT-6.1 3.0.7(0.338/5/3) 2019-04-30 18:08

提前致谢。

【问题讨论】:

  • awk --versionuname -srv 的输出更新你的Q。祝你好运。
  • @shellter 嗨。更新了 awk 版本和系统。
  • 一定要用awk吗?
  • @Shawn Well 不需要。在 Python 或 Ruby 中,我可以选择运行它。或者任何其他可以安装在 Cygwin 上的工具

标签: parsing awk


【解决方案1】:

对于 FIELDWIDTHS,使用 GNU awk(您拥有):

$ cat tst.awk
BEGIN {
    OFS = ","
    print "H1", "H2", "H3", "H4", "H5", "JTT", "JNX", "JNA", "JNO"
}
!NF || ($1 == "JTT") { next }
!/^ / {
    if (NR>1) {
        print rec
    }
    FS = " "
    $0 = $0
    $1 = $1
    rec = $0
}
/^ / {
    FIELDWIDTHS = "12 5 5 *"
    $0 = $0
    $1 = $1
    for (i=1; i<=NF; i++) {
        gsub(/^\s+|\s+$/,"",$i)
    }
    rec = rec OFS $0
}
END {
    print rec
}

.

$ awk -f tst.awk file
H1,H2,H3,H4,H5,JTT,JNX,JNA,JNO
9,8,11,56507785,93,76,,98
9,8,60,3269557,58
9,8,53,7269558,150,132,71,,45-7705678
9,8,62,439559,82

$ awk -f tst.awk file | column -s, -t
H1  H2  H3  H4        H5   JTT  JNX  JNA  JNO
9   8   11  56507785  93   76        98
9   8   60  3269557   58
9   8   53  7269558   150  132  71        45-7705678
9   8   62  439559    82

OFS="," 替换为OFS="\t" 或以其他方式按摩以适应...

【讨论】:

  • 你好,埃德。非常感谢。我只能说效果很好!非常干净的代码。一个问题,你做$0=$0$1=$1的目标是什么?
  • 不客气。 $0=$0 告诉 awk 使用在其正上方定义的 FIELDWIDTHS 或 FS 值重新拆分当前记录,而不是在读取当前记录时填充的 FIELDWIDTHS/FS 值。这是必要的,因为在此之前,当前记录将使用 previous 行中的 FIELDWIDTHS/FS 设置进行拆分。 $1=$1 然后告诉 awk 使用 OFS 的值重新组合当前字段(因此 x y 变为 x,y
  • 感谢您的帮助和解释。
猜你喜欢
  • 1970-01-01
  • 2021-08-04
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多