Awk 如何解析来自不同行的字段以构建包含所有这些文件的新记录

Awk 如何解析来自不同行的字段以构建包含所有这些文件的新记录,awk,sed,rexx,Awk,Sed,Rexx,我有一个具有此结构的文件: 我必须用相同的文本捕获从“ADSTART ACTION(ADD)”行到下一行的所有数据,以创建单个记录或行 很抱歉,我不能发布输出的示例,因为“ADSTART”行之间的所有数据都在一行或记录中,我在z/OS下工作,我们有记录长度的概念 我在REXX for z/OS和AWK for z/OS的UNIX系统服务中尝试了这一点,但我无法将所有字段放在一行中,我不知道如何做到这一点 我通过嵌套循环捕获数据,但我不知道如何将其放在一行中 sed -n '/ADSTART

我有一个具有此结构的文件:

我必须用相同的文本捕获从“ADSTART ACTION(ADD)”行到下一行的所有数据,以创建单个记录或行

很抱歉,我不能发布输出的示例,因为“ADSTART”行之间的所有数据都在一行或记录中,我在z/OS下工作,我们有记录长度的概念

我在REXX for z/OS和AWK for z/OS的UNIX系统服务中尝试了这一点,但我无法将所有字段放在一行中,我不知道如何做到这一点

我通过嵌套循环捕获数据,但我不知道如何将其放在一行中

sed -n '/ADSTART  ACTION(ADD)/,/ADRUN/p'  <filename> | sed 's/ADRUN ACTION(ADD)//g'
sed-n'/ADSTART ACTION(ADD)/,/ADRUN/p'| sed的s/ADRUN ACTION(ADD)//g'

也许这样可以:

awk '/ADSTART  ACTION\(ADD\)/{print buf; buf=""} {buf=buf""$0" "} END{print buf}' test.in
评论版本:

/ADSTART  ACTION\(ADD\)/ { # for records where ADSTART occurs
  print buf                # output the buffer variable
  buf=""                   # then empty the buffer
} 
{                          # for all records
  # gsub(/^ +| +$/,"")     # here you could trim leading and trailing space
  buf=buf""$0" "           # build the buffer 
} 
END {                      # in the end
  print buf                # output the remaining buffer
}

如果您使用的是REXX,那么为什么不使用parse指令来刮取报告文件呢?parse指令使用非常简单但功能强大的模板模式

下面是一个例子:

/* REXX */

queue "ADSTART  ACTION(ADD)"
queue "  ADID(ABCD0B          ) ADVALFROM(111230) CALENDAR(CALSEM7J        )"
queue "  DESCR('DESCRIPTION  ')"
queue "  ADTYPE(A)"
queue "  GROUP(PBQOPC  )"
queue "  OWNER('OWNER1')"
queue "  PRIORITY( 5) ADSTAT(A)"
queue "  ODESCR('ALADIN                  ')"
queue "ADRUN ACTION(ADD)"
queue "  PERIOD(HEB     )  RULE(3) VALFROM(091230)  VALTO(711231)"
queue "  SHIFT(   0)             SHSIGN(F)"
queue "  DESCR('DESCRIPTION')"
queue "  TYPE(N)"
queue "    IADAYS(  1,  2,  3,  4,  5,  6,  7)"
queue "  IATIME(1700) DLDAY(   1)   DLTIME(0600)"

do while queued() > 0
  parse pull rec
  select
    when startswith(rec,"ADSTART") then do
      p. = '' /* the output record */
      parse var rec with . 'ACTION('p.action')'
      do queued()
        parse pull rec
        if left(rec,1) /= ' ' then do
          /* End of parameter group. Re-queue the record and break */
          push rec
          leave
        end
        select
          when startswith(rec, "  ADID") then do
            parse var rec with . "ADID("p.adid") ADVALFROM("p.advalfrom")" ,
              "CALENDAR("p.calendar")"
          end
          when startswith(rec, "  DESCR") then do
            parse var rec with "DESCR('"p.desc"')"
          end
          when startswith(rec, "  PRI") then do
            parse var rec with "PRIORITY("p.priority") ASTAT("p.adstat")"
          end
          otherwise nop
        end
      end
      /* write out the record in 1 line */
      say strip(p.action) strip(p.adid) strip(p.advalfrom) strip(p.calendar),
          strip(p.desc) strip(p.priority) strip(p.adstat)
    end
    when startswith(rec,"ADRUN") then do
      /* do some stuff to parse this */
    end
    otherwise nop
  end
end

exit 0

startswith:
  parse arg input, prefix
  input_len = length(input)
  if input_len = 0 then return 0
  prefix_len = length(prefix)
  if prefix_len = 0 then return 0
  return input_len >= prefix_len & left(input,prefix_len) = prefix
考虑到您在z/OS UNIX环境中的舒适性,如果您想要比REXX和/或AWK更强大的东西,您应该查看我的。它附带了一个函数,使得用很少的代码行编写lexer和parser非常容易

如果您只想将TWS控制语句文本流到一行,而不捕获字段,那么这非常简单

/* REXX */                                                                   

queue "ADSTART  ACTION(ADD)"                                                 
queue "  ADID(ABCD0B          ) ADVALFROM(111230) CALENDAR(CALSEM7J        )"
queue "  DESCR('DESCRIPTION  ')"                                             
queue "  ADTYPE(A)"                                                          
queue "  GROUP(PBQOPC  )"                                                    
queue "  OWNER('OWNER1')"                                                    
queue "  PRIORITY( 5) ADSTAT(A)"                                             
queue "  ODESCR('ALADIN                  ')"                                 
queue "ADRUN ACTION(ADD)"                                                    
queue "  PERIOD(HEB     )  RULE(3) VALFROM(091230)  VALTO(711231)"           
queue "  SHIFT(   0)             SHSIGN(F)"                                  
queue "  DESCR('DESCRIPTION')"                                               
queue "  TYPE(N)"                                                            
queue "    IADAYS(  1,  2,  3,  4,  5,  6,  7)"                              
queue "  IATIME(1700) DLDAY(   1)   DLTIME(0600)"                            

do while queued() > 0                                                        
  parse pull rec                                                             
  if left(rec,1) /= ' ' then do                                              
    line = rec                                                               
    do queued()                                                              
      parse pull rec                                                         
      if left(rec,1) /= ' ' then do                                          
        push rec;leave                                                                
      end                                                                    
      line = line rec                                                        
    end                                                                      
    say space(line,1) 
  end                                                                        
end                                                                          

exit 0     

尽管上述解决方案对每个块的行数不多,但只打印ADSTART操作(ADD)之间的文本并假定只打印一个块的解决方案

狂欢节:

gawk'BEGIN{s=0}/ADSTART.*操作(ADD)/{s=(s+1)%2}(s==1){print}'(sed):a;N、 美元!文学士;s/\n//g'


(ADSTART…行省略)

非常感谢您提供的所有答案

最后,这非常简单,因为当我以二进制格式从z/OS到USS(Unix系统服务for z/OS)进行FTP时,所有数据都在一行中

起初,我用FTP(ASCII xlate)将一个文件传输到我的电脑,然后用WinSCP以二进制FTP传输到USS

这是我用来用回车替换文本模式的代码:

    sed 's/ADSTART  ACTION(ADD)/\
    /g' <input file> ><output file>
sed的/ADSTART操作(添加)/\
/g'>
按回车键插入回车,因为/r/'$''''/n/x0D在USS中不起作用,我不知道为什么

再次感谢大家抽出时间


帕特里西奥。

你的问题不清楚。。并给出一个更小、更简单的示例输入文件和预期输出,而不是这个难以理解的大文件。。同时添加您试图询问的命令。。有关这方面的更多详细信息,请参阅,我已尝试澄清此问题。您可以创建一个包含5-10行的手动示例,并给出相应的示例输出。。再说一次,你也必须展示你在解决问题上的努力。谢谢你,大卫,看起来很有趣!我会检查这个工具。非常感谢