我有一个这种结构的文件:
http://paste.ubuntu.com/21136265/
我必须从线路中获取所有数据' ADSTART ACTION(ADD)'到具有相同文本的下一行,以创建单个记录或行。
很抱歉,但我无法发布输出示例,因为' ADSTART'之间的所有数据都是如此。单行或记录中的行,我在z / OS下工作,我们有记录长度的概念。
我在REXX for z / OS和UNIX系统服务中的AWK中尝试使用z / OS,但是我把所有字段排成一行,我无法弄清楚如何做它
我通过嵌套循环捕获数据,但我不知道如何将它放在一行中。
任何想法都会被贬低。
先谢谢。
帕特里西奥。
答案 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中没有用,我不知道为什么。
再次感谢你们所有的时间。
帕特里西奥。