Windows脚本从命令输出中解析WebSphere JVM的名称

时间:2014-01-08 00:20:54

标签: regex windows batch-file vbscript websphere

我正在编写一个(批处理文件或VBScript)来很好地关闭Windows服务器上所有正在运行的WebSphere JVM,但需要一些文本处理方面的帮助。我希望脚本运行并解析“serverstatus”命令的输出,以获取框中 应用程序服务器 的名称,并存储匹配项(带回车符)用于脚本其余部分的变量。

示例命令输出:

C:\WebSphere\AppServer\bin>serverstatus -all
ADMU0116I: Tool information is being logged in file
       C:\WebSphere\AppServer\profiles\MySrv01\logs\serverStatus.log
ADMU0128I: Starting tool with the MySrv01 profile
ADMU0503I: Retrieving server status for all servers
ADMU0505I: Servers found in configuration:
ADMU0506I: Server name: MyCluster_MySrv01
ADMU0506I: Server name: MyCluster_MySrv01_1
ADMU0506I: Server name: MyNextCluster_MySrv04
ADMU0506I: Server name: MyNextCluster_MySrv04_1
ADMU0506I: Server name: nodeagent
ADMU0508I: The Application Server "MyCluster_MySrv01" is STARTED
ADMU0508I: The Application Server "MyCluster_MySrv01_1" is STARTED
ADMU0508I: The Application Server "MyNextCluster_MySrv04" is STARTED
ADMU0509I: The Application Server "MyNextCluster_MySrv04_1" cannot be
       reached. It appears to be stopped.
ADMU0508I: The Node Agent "nodeagent" is STARTED

* nodeagent不应该匹配。对于我是否要针对所有应用服务器或只是那些状态为“已启动”的应用服务器,评审团仍然没有考虑。

2 个答案:

答案 0 :(得分:1)

使用RegExp切断输入中的引用名称;添加上下文 - 服务器,已启动 - 微调结果集。在代码中:

Option Explicit

Function q(s) : q = "'" & s & "'" : End Function

Dim sInp : sInp = Join(Array( _
   "ADMU0116I: Tool information is being logged in file C:\WebSphere\AppServer\profiles\MySrv01\logs\serverStatus.log" _
 , "ADMU0128I: Starting tool with the MySrv01 profile" _
 , "ADMU0503I: Retrieving server status for all servers" _
 , "ADMU0505I: Servers found in configuration:" _
 , "ADMU0506I: Server name: MyCluster_MySrv01" _
 , "ADMU0506I: Server name: MyCluster_MySrv01_1" _
 , "ADMU0506I: Server name: MyNextCluster_MySrv04" _
 , "ADMU0506I: Server name: MyNextCluster_MySrv04_1" _
 , "ADMU0506I: Server name: nodeagent" _
 , "ADMU0508I: The Application Server ""MyCluster_MySrv01"" is STARTED" _
 , "ADMU0508I: The Application Server ""MyCluster_MySrv01_1"" is STARTED" _
 , "ADMU0508I: The Application Server ""MyNextCluster_MySrv04"" is STARTED" _
 , "ADMU0509I: The Application Server ""MyNextCluster_MySrv04_1"" cannot be reached. It appears to be stopped." _
 , "ADMU0508I: The Node Agent ""nodeagent"" is STARTED" _
), vbCrLf)

Dim aRes : aRes = Array( _
    Array("all quoted names", """([^""]+)""") _
  , Array("all quoted started servers", "Server ""([^""]+)"" is STARTED") _
)

Dim aRE
For Each aRe In aRes
    WScript.Echo "----------------", q(aRe(0)), q(aRe(1))
    Dim re : Set re = New RegExp
    re.Global = True
    re.Pattern = aRe(1)
    Dim oMTS : Set oMTS = re.Execute(sInp)
    ReDim a(oMTS.Count - 1)
    Dim i
    For i = 0 To UBound(a)
        a(i) = q(oMTS(i).SubMatches(0))
    Next
    WScript.Echo " =>", Join(a)

Next

输出:

cscript 20984738.vbs
---------------- 'all quoted names' '"([^"]+)"'
 => 'MyCluster_MySrv01' 'MyCluster_MySrv01_1' 'MyNextCluster_MySrv04' 'MyNextCluster_MySrv04_1' 'nodeagent'
---------------- 'all quoted started servers' 'Server "([^"]+)" is STARTED'
 => 'MyCluster_MySrv01' 'MyCluster_MySrv01_1' 'MyNextCluster_MySrv04'

答案 1 :(得分:1)

这是使用Regex的替代方法。它只是读取stdout并处理所有已启动的应用服务器 - 应用服务器存储在名为AppServers的数组中。在W2K3上测试过。 编辑:我们添加了一种方法,通过添加日志写入函数将输出记录到文件中(不要忘记在我们刚刚添加到此答案的脚本开头添加const ForAppending)。日志写入功能采用以下格式:

Logwrite "some text to write - delete file if exists", "c:\Path\filename.txt", 1
Logwrite "some text to write - append to file, don't delete", "c:\path\filename.txt", 0

这是一个粗略的功能,但你做的是什么。我希望有所帮助。 :)

option explicit
Const ForAppending = 8
Dim objShell, objWshScriptExec, objStdOut
Dim objCmdString, strLine, appServers(), maxAppServers
Dim x

' File Path / Location to serverstatus.bat ----
objCmdString = "C:\WebSphere\AppServer\bin\serverstatus.bat -all"

Set objShell = CreateObject("WScript.Shell")
Set objWshScriptExec = objShell.Exec(objCmdString)
Set objStdOut = objWshScriptExec.StdOut

MaxAppServers = -1

' While we're looping through the response from the serverstatus command, look for started application servers
' and store them in an ever expanding array AppServers.
' The Variable MaxAppServers should always contain the highest number of AppServers (ie: ubound(AppServers))

While Not objStdOut.AtEndOfStream
   strLine = objStdOut.ReadLine
   If InStr(LCase(strLine), "admu0508i: the application server """) Then
      MaxAppServers = MaxAppServers + 1
      ReDim Preserve AppServers(MaxAppServers)
      AppServers(MaxAppServers) = wedge(strLine, Chr(34))
   End If
Wend

If MaxAppServers => 0 then 
    For x = 0 To ubound(AppServers)    ' You could just use For x = 1 to MaxAppServers in this case.
        ' Add your instructions here.........
        ' ... We are simply echoing out the AppServer name below as an example to a log file as requested below.
         Logwrite AppServers(x), "c:\Output.log", 0
    Next
End If

Function Wedge(wStr, wOpr)
' This clunky function simply grabs a section of a string the is encapsulated by wOpr.
' NOTE: This function expects wOpr to be a single character (eg; for our purpose, it is pulling data between double quotes).

    Dim wFlag, wCount, wFinish

    wflag = False
    wFinish = False
    wCount = 1
    Wedge = ""

    Do Until wCount > Len(wStr) Or wFinish
       If Mid(wStr, wCount, 1) = wOpr Then
           If wFlag Then
              wFinish = True
           Else
              wFlag = True
           End If
       Else
           If wFlag Then Wedge = Wedge & Mid(wStr, wCount, 1)                                 
       End If
       wCount = wCount + 1
    Loop
 End Function

Function logwrite (lstrtxt, lwLogfile, lwflag)
    Dim lwObjFSO, lwObjFile, fstr, lwcounter, lwc
    fstr = lstrtxt
    Set lwObjFSO = CreateObject("Scripting.FileSystemObject")
    If lwflag=1 And lwObjFSO.FileExists(lwLogFile) Then lwObjfso.deletefile(lwLogFile)
    If lwObjFSO.FileExists(lwLogFile) then
        On Error Resume next
        Set lwObjFile = lwObjFSO.OpenTextFile(lwLOgFile, ForAppending)
        lwCounter = 20000
        Do While Err.number = 70 And lwCounter > 0
            wscript.echo "ERROR: Retrying output - Permission denied; File may be in use!"
            For lwc = 1 To 1000000
            Next
            Err.clear
            Set lwObjFile = lwObjFSO.OpenTextFile(lwLogFile, ForAppending)
            lwCounter = lwCounter-1
        Loop
        If Err.number <> 0 Then
            wscript.echo "Error Number: "&Err.number
            wscript.quit
        End If
        On Error goto 0
    Else
        Set lwObjFile = lwObjFSO.CreateTextFile(lwLogFile)
    End If
    wscript.echo (fstr)
    lwObjFile.Write (fstr) & vbcrlf
    lwObjFile.Close
    Set lwObjFSO=Nothing
    Set lwObjfile=Nothing

 End Function