正则表达式匹配 JCL 工作卡或整张卡的最后一行

问题描述 投票:0回答:5

如果你们熟悉大型机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(.)*)
regex parsing ansible mainframe jcl
5个回答
2
投票

在一般情况下解析 JCL 是很难。正如评论中指出的,规则充满了警告。

我有一个 ANTLR4 JCL 语法,它已获得 MIT 许可。 可能有用。体现了JCL的美丽。


1
投票

要匹配整个工作卡(在本例中为 3 行):

(?sm)\A.*?\/\/[^*]((?!\/\*)[^\n])*[^,]$

参见现场演示

分解:

  • (?sm)
    • s
      启用 DOTALL 标志(意味着
      .
      也匹配新行)
    • m
      启用 MUTLILINE 标志(意味着
      ^
      $
      匹配行的开头和结尾
  • \A
    表示输入开始(所以只在最开始匹配)
  • .*?
    意味着任何东西,但尽可能少
  • //[^*]
  • ((?!\/\*)[^\n])*
    表示非新行,除了序列
    /*
    (因此当注释放入行时不匹配)
  • [^,]
    不是逗号
  • $
    行尾

英文:“从头开始匹配,直到一行末尾有一个非逗号,不是注释,或者不以注释结尾”

然后您将替换为

$0
(第 0 组是整个比赛),然后是您注入的内容:

$0\\n*ROUTE statement

0
投票

为此,您可以使用 负向回顾

(?<!,)

但您还需要在
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

0
投票

对于一般情况,这比您想象的要困难,因为在工作卡范围内允许发表评论。

    //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

您显示的字符串:

  • <--- start of job card
  • 行=(999999,警告),
  • <--- 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+

但是我不太了解正则表达式,无法找到“就在之前”的点来插入新行。希望其他人可以补充。


0
投票

不完全正确:您的 JOB 卡以 //name JOB 开头,并在下一个 >//name 卡之前结束。名称在所有 JCL 语句中都是可选的,除了 JOB > 语句。例如。在 SET 语句中通常没有名称;不需要它,因为>你无法引用它。 – phunsoft,2021 年 12 月 11 日 9:29

也不完全正确。 您可以使用 // EXEC PGM= 而不带步骤名称,这也会结束 JOB 语句。

© www.soinside.com 2019 - 2024. All rights reserved.