如果你们熟悉大型机JCL。
我正在尝试匹配工作卡的最后一行。
基本上第一行以
//
开头,不以逗号结尾。
在示例中,我需要第 3 行或最多第 3 行匹配。
我正在使用 Ansible 的
lineinfile
在作业卡之后动态插入路线卡。
例如:
//SPOOL1 JOB (UU999999999,1103),'Programmer',CLASS=0, <--- start of job card
// REGION=0M,MSGCLASS=R,TIME=5, LINES=(999999,WARNING),
// NOTIFY=&SYSUID <--- end of job card
//STEPNAME EXEC PGM=BPXBATCH
//STDERR DD SYSOUT=*
//STDOUT DD SYSOUT=*
//STDPARM DD *
SH cat /dev/urandom
到目前为止,我得到了这个,它与
//
的开头以及之后的任何内容相匹配,但是,我无法弄清楚最后一部分
^(\Q//\E(.)*)
在一般情况下解析 JCL 是很难。正如评论中指出的,规则充满了警告。
我有一个 ANTLR4 JCL 语法,它已获得 MIT 许可。 可能有用。体现了JCL的美丽。
要匹配整个工作卡(在本例中为 3 行):
(?sm)\A.*?\/\/[^*]((?!\/\*)[^\n])*[^,]$
参见现场演示。
分解:
(?sm)
s
启用 DOTALL 标志(意味着 .
也匹配新行)m
启用 MUTLILINE 标志(意味着 ^
和 $
匹配行的开头和结尾\A
表示输入开始(所以只在最开始匹配).*?
意味着任何东西,但尽可能少//[^*]
((?!\/\*)[^\n])*
表示非新行,除了序列 /*
(因此当注释放入行时不匹配)[^,]
不是逗号$
行尾英文:“从头开始匹配,直到一行末尾有一个非逗号,不是注释,或者不以注释结尾”
然后您将替换为
$0
(第 0 组是整个比赛),然后是您注入的内容:
$0\\n*ROUTE statement
为此,您可以使用 负向回顾:
(?<!,)
。firstmatch
之后插入并使用 backrefs
。
给定任务:
- lineinfile:
path: file.jcl
regexp: '^(\/\/.*)(?<!,)$'
line: "\\1\\n//*ROUTE statement"
firstmatch: true
backrefs: true
从你的例子来看,你最终会得到:
//SPOOL1 JOB (UU999999999,1103),'Programmer',CLASS=0,
// REGION=0M,MSGCLASS=R,TIME=5, LINES=(999999,WARNING),
// NOTIFY=&SYSUID
//*ROUTE statement
//STEPNAME EXEC PGM=BPXBATCH
//STDERR DD SYSOUT=*
//STDOUT DD SYSOUT=*
//STDPARM DD *
SH cat /dev/urandom
对于一般情况,这比您想象的要困难,因为在工作卡范围内允许发表评论。
//SPOOL1 JOB (UU999999999,1103),'Programmer',CLASS=0, <--- start of job card
// REGION=0M,MSGCLASS=R,TIME=5, LINES=(999999,WARNING),
// NOTIFY=&SYSUID <--- end of job card
您显示的字符串:
在 JCL 中作为注释都是有效的,因为它们后面有一个空格。
您甚至可以在工作卡中包含完整的注释行。例如:
//name JOB (accounting info),'data capture ___',
//* TYPRUN=SCAN,
// NOTIFY=&SYSUID,
// CLASS=A,MSGCLASS=T,MSGLEVEL=(1,1),TIME=(5,00),
// REGION=5M
因此,您不一定要寻找第一张不以逗号结尾的卡片,除非您可以限制您正在查看的 JCL。
您的工作卡以 //name JOB 开头,并在下一张 //name 卡之前结束。 *** 编辑 *** 正如正确指出的那样,作业卡后面可以跟一张不需要名称字段的卡,例如 // SET。请参阅 https://www.ibm.com/docs/en/zos/2.4.0?topic=statements-jcl-statement-fields *** 编辑结束 ***
以 ^(\Q//\E)[A-Z0-9]+\s+\QJOB\E.+ 开头 并在下一张指定卡片之前结束 ^(\Q//\E)[A-Z0-9]+\s+
但是我不太了解正则表达式,无法找到“就在之前”的点来插入新行。希望其他人可以补充。
不完全正确:您的 JOB 卡以 //name JOB 开头,并在下一个 >//name 卡之前结束。名称在所有 JCL 语句中都是可选的,除了 JOB > 语句。例如。在 SET 语句中通常没有名称;不需要它,因为>你无法引用它。 – phunsoft,2021 年 12 月 11 日 9:29
也不完全正确。 您可以使用 // EXEC PGM= 而不带步骤名称,这也会结束 JOB 语句。