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

时间:2016-07-27 11:44:31

标签: awk sed rexx

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

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

我必须从线路中获取所有数据' ADSTART ACTION(ADD)'到具有相同文本的下一行,以创建单个记录或行。

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

我在REXX for z / OS和UNIX系统服务中的AWK中尝试使用z / OS,但是我把所有字段排成一行,我无法弄清楚如何做它

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

任何想法都会被贬低。

先谢谢。

帕特里西奥。

5 个答案:

答案 0 :(得分:1)

如果您正在使用REXX,那么为什么不使用解析指令来抓取报告文件?解析指令使用非常简单但功能强大的模板模式。

以下是一个例子:

html

看到您在z / OS UNIX环境中感到满意,如果您想要比REXX和/或AWK更强大的功能,您应该检查我的z/OS port of Lua。它带有一个LPeg package,这使得用简单的代码行编写词法分析器和解析器变得非常简单。

如果您想要做的只是文本将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
  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

答案 1 :(得分:0)

试试这个;

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

答案 2 :(得分:0)

也许会这样做:

var underscoreToCamelCase = function(str) {
    str = (str === undefined || str === null) ? '' : str;
    str = str.replace(/_/g, " ").toLowerCase();
    return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function(match, index) {
        if (+match === 0) return "";
        return index == 0 ? match.toLowerCase() : match.toUpperCase();
    });
}

评论版:

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

答案 3 :(得分:0)

虽然上面的解决方案可以用于每个块的行数不多,但是只打印ADSTART ACTION(ADD)之间的文本并且只打印一个块的解决方案

击:

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

(ADSTART ...行被省略)

答案 4 :(得分:0)

非常感谢您的所有答案。

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

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

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

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

按回车键插入回车符,因为/ r /'$'''/ n / x0D在USS中没有用,我不知道为什么。

再次感谢你们所有的时间。

帕特里西奥。