0

我有一个批处理脚本,它将所有文件(包括路径和版本号)写入物理设备的 TMP 文件。然后,此批处理脚本会写入任何显示文件版本号大于提供的变量的行。

DIRECTORYX := DIRECTORY /NODATE /NOHEADING /NOTRAILING
DIR_OUTPUT_FILENAME = "TOPAS$UTILLOG:" + F$UNIQUE() + ".TMP"
DEVICE = $1$DGA1112
DIRECTORYX 'DEVICE':[000000...]*.*;* /NOSIZE /OUTPUT='DIR_OUTPUT_FILENAME'

同时,我有一些我不感兴趣的文件被报告给我。在这种情况下,我想从 TMP 文件中删除任何可能包含此文件名 ( filename.ext; ) 的行,以便批处理脚本可以继续通过它,并且只报告我不想明确忽略的文件。

我将如何在循环中使用“IGNORE_FILE”作为文本字符串的变量来读取文件以匹配并删除关联的文本行,以便当我的批处理脚本继续执行文件时,它不会报告请求的文件忽略。

非常感谢您的帮助

4

2 回答 2

1

两条评论都是一个很好的开始。仔细检查它们。哪个 OpenVMS 版本?过去 2 年的东西?

只需抓住并使用 DFU !

$ define/user sys$output nl:
$ mcr dfu searc/versio=min=200/excl=(*.dat,*.tmp)/form="!AS"/out=tmp.tmp dka0:
$ type tmp.tmp
BUNDY$DKA0:[SYS0.SYSMGR]OPERATOR.LOG;242
BUNDY$DKA0:[SYS0.SYSMGR]ACME$SERVER.LOG;241
BUNDY$DKA0:[SYS0.SYSMGR]LAN$ACP.LOG;241

您还可以考虑将 F$SEARCH 放在一个循环中并解析出版本和其他有趣的组件来实现您的排除...。

$
$ type SEARCH_HIGH_VERSION.COM
$ max = 200
$ old = ""
$ IF p1.EQS."" THEN EXIT 16 ! PARAM
$loop:
$ file = F$SEARC(p1)
$ IF file.EQS."" THEN EXIT 99018 ! NMF
$ IF file.EQS.old THEN EXIT 100164 ! Not wild
$ old = file
$ version = F$PARSE(file,,,"VERSION") - ";"
$ IF max.GE.'version' THEN GOTO loop
$ ! IF ... further string tests
$ WRITE SYS$OUTPUT file
$ GOTO LOOP
$
$ @SEARCH_HIGH_VERSION.COM *.*;*
SYS$SYSROOT:[SYSMGR]ACME$SERVER.LOG;241
SYS$SYSROOT:[SYSMGR]LAN$ACP.LOG;241
SYS$SYSROOT:[SYSMGR]OPERATOR.LOG;242
SYS$SYSROOT:[SYSMGR]TMP.TMP;304
SYS$SYSROOT:[SYSMGR]TMP.TMP;303
SYS$SYSROOT:[SYSMGR]TMP.TMP;302
SYS$SYSROOT:[SYSMGR]TMP.TMP;301
SYS$SYSROOT:[SYSMGR]TMP.TMP;300
%RMS-E-NMF, no more files found
$
$ @SEARCH_HIGH_VERSION.COM tmp.tmp
SYS$SYSROOT:[SYSMGR]TMP.TMP;304
%RMS-F-WLD, invalid wildcard operation
$

DFU 可能会比 DIR 快 10* DIR 会比 F$SEARCH 快 10*,但你会在处理过程中失去它。

祝你好运!海因

于 2014-03-13T04:54:23.990 回答
1

好吧...现在我知道你从哪里来了。

我将如何写从第 7 到行尾的所有内容?

好吧,您可以从 i=7 开始循环,或者您可以使用“引号”字符串并将引号用作新的分隔符。这是两者的示例,使用双引号作为几乎自然的第二分隔符选择

$
$ READ SYS$INPUT BUFF
SHG101,$1$DGA1101:,25,15,10,5000,100,X.TMP,Y.DAT
$
$ excludes = ""
$ tmp = F$ELEMENT(7, ",", BUFF)
$ IF tmp.NES.","
$ THEN
$   i = 8
$   excludes = tmp
$exclude_loop:
$   tmp = F$ELEMENT(i, ",", BUFF)
$   IF tmp.NES.","
$   THEN
$      excludes = excludes + "," + tmp
$      i = i + 1
$      GOTO exclude_loop
$   ENDIF
$   excludes = "/EXCLUDE=(" + excludes + ")"
$ ENDIF
$
$ SHOW SYMB excludes
$
$! Using a different delimitor:
$ READ SYS$INPUT BUFF
SHG101,$1$DGA1101:,25,15,10,5000,100,"X.TMP,Y.DAT"
$
$ excludes = ""
$ tmp = F$ELEMENT(1, """", BUFF)
$ IF tmp.NES."," THEN excludes = "/EXCLUDE=(" + tmp + ")"
$
$ SHOW SYMB excludes

在我们看到的代码中: 检查 ''DEVICE' 是否有高文件版本 (>= ;''HVERNO') - 可能需要一些时间...>

我敦促您查看 DFU 大循环代码“ READ FH3 /END_OF_FILE=LABEL$_EOF_DIRLIST1 BUFF2... ”将简化为:

dfu searc/versio=min=200'excludes'form="!AS"/out=tmp.tmp dka0:

无论有多少文件,这几乎都将在几秒钟内运行。扔掉整个警告内容,包括它总是检查 32000,因为它(几乎)是免费的。执行 DFU 命令后,如果 tmp.tmp 不为空,则通过创建标头并附加 tmp.tmp 创建“fancy”输出。总是删除 tmp.tmp ($ CLOSE/DISP=DELETE )

免费咨询...

那些 15 深嵌套的 IF-THEN-ELSE-ENDIF 来接收消息看起来很糟糕(维护)考虑数组查找?!这是一个已解决的示例:

$! prep for test
$ EL = p1
$ EL_DIAG = "FILE.DAT"
$ LOCAL_STATUS = "12345"
$
$! Code snippet to be tested
$
$ x  = 'EL'
$ ! Fold multiple conditions into 1 message
$
$ if  (EL .EQ. 7) .OR. (EL .EQ. 14) .OR. (EL .EQ. 21) .OR. (EL .EQ. 25) -
                .OR. (EL .EQ. 29) .OR. (EL .EQ. 30)  THEN x = "L1"
$
$ MSG_6     = "error opening "       + EL_DIAG + " for WRITE (RM=" + LOCAL_STATUS + ")"
$ IDT_6     = "OPENIN"
$ MSG_L1    = "error reading from "  + EL_DIAG + " (RM=" + LOCAL_STATUS + ")"
$ IDT_L1    = "READERR"
$ MSG_8     = "device name missing " + EL_DIAG
$ IDT_8     = "DNNF"
$
$ ! Pick up the required texts
$
$ IF F$TYPE(MSG_'x').EQS.""
$ THEN
$   WRITE SYS$OUTPUT "No message found for code: ", EL
$   EXIT 16
$ ENDIF
$
$ MSG   = MSG_'x
$ IDTXT = IDT_'x
$
$ WRITE SYS$OUTPUT "MSG  : ", MSG
$ WRITE SYS$OUTPUT "IDTXT: ", IDTXT

干杯,海因

于 2014-03-15T16:25:20.483 回答