awk向下填充并生成由&;分隔的间隔;及&;:

awk向下填充并生成由&;分隔的间隔;及&;:,awk,Awk,希望读取第一个字段,然后根据“&-”和“&&-”增加间隔 示例输入.txt DIGITS AL DEST CHI CNT NEDEST CORG NCHA 20 0 ABC 1 N ABC000 0 CHARGE 1 ABC 1 N ABC111

希望读取第一个字段,然后根据“&-”和“&&-”增加间隔

示例输入.txt

DIGITS                   AL DEST         CHI CNT NEDEST       CORG  NCHA   
20                        0 ABC          1   N   ABC000       0     CHARGE      
                          1 ABC          1   N   ABC111       0     CHARGE      
                          2 ABC          1   N   ABC222       0     CHARGE      
                          3 ABC          1   N   ABC333       0     CHARGE      
                          4 ABC          1   N   ABC444       0     CHARGE      
210&-2                    0 ABC          1   N   ABC000       0     CHARGE      
                          1 ABC          1   N   ABC111       0     CHARGE      
                          2 ABC          1   N   ABC222       0     CHARGE      
                          3 ABC          1   N   ABC333       0     CHARGE      
                          4 ABC          1   N   ABC444       0     CHARGE      
2130&&-3&-6&&-8           0 ABC          1   N   ABC000       0     CHARGE      
                          1 ABC          1   N   ABC111       0     CHARGE      
                          2 ABC          1   N   ABC222       0     CHARGE      
                          3 ABC          1   N   ABC333       0     CHARGE      
                          4 ABC          1   N   ABC444       0     CHARGE 
期望输出:

DIGITS                   AL DEST         CHI CNT NEDEST       CORG  NCHA   
20                        0 ABC          1   N   ABC000       0     CHARGE      
20                        1 ABC          1   N   ABC111       0     CHARGE      
20                        2 ABC          1   N   ABC222       0     CHARGE      
20                        3 ABC          1   N   ABC333       0     CHARGE      
20                        4 ABC          1   N   ABC444       0     CHARGE      
210                       0 ABC          1   N   ABC000       0     CHARGE      
210                       1 ABC          1   N   ABC111       0     CHARGE      
210                       2 ABC          1   N   ABC222       0     CHARGE      
210                       3 ABC          1   N   ABC333       0     CHARGE      
210                       4 ABC          1   N   ABC444       0     CHARGE      
212                       0 ABC          1   N   ABC000       0     CHARGE      
212                       1 ABC          1   N   ABC111       0     CHARGE      
212                       2 ABC          1   N   ABC222       0     CHARGE      
212                       3 ABC          1   N   ABC333       0     CHARGE      
212                       4 ABC          1   N   ABC444       0     CHARGE      
2130                  0 ABC          1   N   ABC000       0     CHARGE      
2130                      1 ABC          1   N   ABC111       0     CHARGE      
2130                      2 ABC          1   N   ABC222       0     CHARGE      
2130                      3 ABC          1   N   ABC333       0     CHARGE      
2130                      4 ABC          1   N   ABC444       0     CHARGE 
2131                      0 ABC          1   N   ABC000       0     CHARGE      
2131                      1 ABC          1   N   ABC111       0     CHARGE      
2131                      2 ABC          1   N   ABC222       0     CHARGE      
2131                      3 ABC          1   N   ABC333       0     CHARGE      
2131                      4 ABC          1   N   ABC444       0     CHARGE 
2132                      0 ABC          1   N   ABC000       0     CHARGE      
2132                      1 ABC          1   N   ABC111       0     CHARGE      
2132                      2 ABC          1   N   ABC222       0     CHARGE      
2132                      3 ABC          1   N   ABC333       0     CHARGE      
2132                      4 ABC          1   N   ABC444       0     CHARGE 
2133                      0 ABC          1   N   ABC000       0     CHARGE      
2133                      1 ABC          1   N   ABC111       0     CHARGE      
2133                      2 ABC          1   N   ABC222       0     CHARGE      
2133                      3 ABC          1   N   ABC333       0     CHARGE      
2133                      4 ABC          1   N   ABC444       0     CHARGE 
2136                      0 ABC          1   N   ABC000       0     CHARGE      
2136                      1 ABC          1   N   ABC111       0     CHARGE      
2136                      2 ABC          1   N   ABC222       0     CHARGE      
2136                      3 ABC          1   N   ABC333       0     CHARGE      
2136                      4 ABC          1   N   ABC444       0     CHARGE 
2137                      0 ABC          1   N   ABC000       0     CHARGE      
2137                      1 ABC          1   N   ABC111       0     CHARGE      
2137                      2 ABC          1   N   ABC222       0     CHARGE      
2137                      3 ABC          1   N   ABC333       0     CHARGE      
2137                      4 ABC          1   N   ABC444       0     CHARGE 
2138                      0 ABC          1   N   ABC000       0     CHARGE      
2138                      1 ABC          1   N   ABC111       0     CHARGE      
2138                      2 ABC          1   N   ABC222       0     CHARGE      
2138                      3 ABC          1   N   ABC333       0     CHARGE      
2138                      4 ABC          1   N   ABC444       0     CHARGE 

在开始和结束的基本级别生成连续序列,而不是在这个复杂级别。谷歌搜索了很多类似的解决方案,但运气不佳。任何建议…

一个想法是使用第一列中的数字代码作为记录分隔符将数据拆分为多行记录(需要正则表达式RS,如在gawk中)。因此,一个记录的例子是

记录分隔符(存储在RT中):
2130&&-3&-6&&-8
记录:
0 ABC 1 N ABC000 0费用
1 ABC 1 N ABC111 0费用
2 ABC 1 N ABC222 0收费
3 ABC 1 N ABC333 0费用
4 ABC 1 N ABC444 0费用
编写一个print函数来打印以数字为前缀的行,并为每行应以数字为前缀的数字调用一次

要计算前缀号,请编写一个函数,该函数对记录分隔符文本中的数字代码进行操作,计算下一个前缀号(
number
)以及数字代码的新值(
numcode
)。
number
numcode
都可以是全局的。对于循环控制,如果没有更多的前缀号,函数应返回0;1否则

计算
number
numcode
的规则如下:

如果numcode是空字符串,则返回0。
将数字设置为numcode中的初始数字(在任何符号和之前)
如果numcode只是一个数字:
将numcode设置为空字符串
如果numcode中的数字后面有一个符号AND:
将numcode中数字的最后一位更改为第一个破折号后的数字
删除第一个&n子字符串
如果numcode中的数字后面有两个与符号:
通过向numcode中添加一个数字来更改数字的最后一位
如果它等于第一个破折号后的数字
删除第一个&&-n子字符串
返回1
示例:

numcode in number是numcode out返回值
""                                        0
120          120          ""              1
120&-2       120          122             1
120&-2&-4    120          122&-4          1
120&&-3      120          121&&-3         1
121&&-3      121          122&&-3         1
122&&-3      122          123             1
扩展示例:

numcode-in-number numcode-out返回值
120&&-2&-5&&-7   120      121&&-2&-5&&-7    1
121&&-2&-5&&-7   121      122&-5&&-7        1
122&-5&&-7       122      125&&-7           1
125&&-7          125      126&&-7           1
126&&-7          126      127               1
127              127      ""                1
""               --       --                0
骨架代码:

gawk '
  # Global numcode (in,out), number(out)
  function seqcalc() {
    if (numcode == "") return 0
    number = """initial digits of numcode"""
    numcode = """next value of numcode"""
    return 1
  }

  # Global number(in), $0(in)
  function printlines(          line) {
    for ("""each line in $0""")
      sub(/^[ \t]+/, "", line)
      printf(%-26s%s\n", number, line)
  }

  BEGIN { RS = "(^|\n)[^ ]+" }
  {
    while (seqcalc())  # first time numcode=="" so seqcalc() returns 0
      printlines()
    numcode = RT
    sub(/^\n/, "", numcode)
  }
' file

谢谢ooga,我得到下面的错误,请建议,gawk:cmd。行:12:for(“$0”“中的每行”)gawk:cmd。第12行:^语法错误gawk:cmd。第14行:printf(%-26s%s\n“,数字,行)gawk:cmd。第14行:^语法错误gawk:cmd。第14行:printf(%-26s%s\n“,数字,行)gawk:cmd。第14行:^反斜杠不是gawk:cmd行的最后一个字符。行:14:printf(%-26s%s\n“,数字,行)gawk:cmd.line:14:^语法error@AVN我建议您修复这些明显的语法错误,并填写缺少的代码。
“numcode的初始数字”
“numcode的下一个值”
和“$0中的每一行”“`不是神奇的代码片段,只是需要编写的代码的占位符。
printf
显然缺少双引号。
gawk '
  # Global numcode (in,out), number(out)
  function seqcalc() {
    if (numcode == "") return 0
    number = """initial digits of numcode"""
    numcode = """next value of numcode"""
    return 1
  }

  # Global number(in), $0(in)
  function printlines(          line) {
    for ("""each line in $0""")
      sub(/^[ \t]+/, "", line)
      printf(%-26s%s\n", number, line)
  }

  BEGIN { RS = "(^|\n)[^ ]+" }
  {
    while (seqcalc())  # first time numcode=="" so seqcalc() returns 0
      printlines()
    numcode = RT
    sub(/^\n/, "", numcode)
  }
' file