-4

我有一个具有这种结构的文件:

http://paste.ubuntu.com/21136265/

而且我必须使用相同的文本将'ADSTART ACTION(ADD)'行中的所有数据捕获到下一行,以创建单个记录或行。

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

我正在 REXX for z/OS 和 AWK 中的 UNIX SYSTEM SERVICES for z/OS 中尝试此操作,但我坚持将所有字段排成一行,我不知道该怎么做。

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

4

5 回答 5

1

如果您使用的是 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 更强大的东西,您应该查看我的 Lua z/OS 端口。它带有一个LPeg 包,这使得用很少的代码行编写词法分析器和解析器变得非常容易。

如果您只想将 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     
于 2016-07-29T04:30:09.503 回答
0

非常感谢您的所有回答。

最后,这很容易,因为当我以二进制形式从 z/OS 到 USS(用于 z/OS 的 Unix 系统服务)进行 FTP 时,所有数据都在一行中。

起初,我正在处理通过 FTP (ASCII xlate) 传输到我的 PC 的文件,然后使用 WinSCP 以二进制 FTP 传输到 USS。

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

    sed 's/ADSTART  ACTION(ADD)/\
    /g' <input file> ><output file>

通过按回车键插入回车,因为 /r /'$''' /n /x0D 在 USS 中不起作用,我不知道为什么。

再次感谢大家的时间。

帕特里西奥。

于 2016-08-02T12:03:11.257 回答
0

尽管上面的解决方案可能适用于每个块的行数不多,但仅打印 ADSTART ACTION (ADD) 之间的文本并假设只打印一个块的解决方案

重击:

gawk 'BEGIN{s=0} /ADSTART.*ACTION(ADD)/ {s=(s+1)%2} (s==1){ print }' | sed ':a;N;$!ba;s/\n//g'

(ADSTART... 行被省略)

于 2016-08-01T19:12:34.463 回答
0

尝试这个;

sed -n '/ADSTART  ACTION(ADD)/,/ADRUN/p'  <filename> | sed 's/ADRUN ACTION(ADD)//g'
于 2016-07-28T07:59:19.287 回答
0

也许这会做到:

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
}
于 2016-07-28T08:00:23.210 回答