Batch file 脚本以在多行中查找模式,并回显与模式匹配的计算机名

Batch file 脚本以在多行中查找模式,并回显与模式匹配的计算机名,batch-file,vbscript,Batch File,Vbscript,我有一个文本文件,其中包含从PowerShell脚本导入的数据。数据是域笔记本电脑上BitLocker的状态。文本文件包含的内容示例如下: 电脑名称:Computer1 转换状态:完全加密 保护状态:对设备的保护 电脑名称:Computer2 转换状态:完全加密 保护状态:保护关闭 电脑名称:Computer3 转换状态:已完全解密 保护状态:保护关闭 转换状态:完全加密 保护状态:对设备的保护 我要寻找的是一个脚本,它将搜索两个特定行相邻的所有实例。例如,在文本文件中,我需要脚本来查找转换状态

我有一个文本文件,其中包含从PowerShell脚本导入的数据。数据是域笔记本电脑上BitLocker的状态。文本文件包含的内容示例如下:

电脑名称:Computer1 转换状态:完全加密 保护状态:对设备的保护 电脑名称:Computer2 转换状态:完全加密 保护状态:保护关闭 电脑名称:Computer3 转换状态:已完全解密 保护状态:保护关闭 转换状态:完全加密 保护状态:对设备的保护 我要寻找的是一个脚本,它将搜索两个特定行相邻的所有实例。例如,在文本文件中,我需要脚本来查找转换状态:完全加密和保护状态:保护关闭的行的位置。然后,一旦满足了这个要求,这两行上面的计算机名称就需要被回显或通过管道传输到一个文本文件中。在上面的例子中,它将是Computer2。需要考虑的是,一些系统具有多个硬盘驱动器或分区,它们具有BitLocker的单独状态。因此,一个系统在文本文件中可能有两个条目,如上面示例中的Computer3


我想要的最终结果是一个文本文件,其中只包含转换状态为“完全加密”和“保护状态:保护关闭”的计算机名。我的脚本编写技能非常有限,但我能够解决这些问题。这一个让我和其他与我一起工作的管理员一样感到困惑。任何帮助或指导都将不胜感激

如果要逐行处理文件,并根据多行内容执行某些操作,则需要记住/保持以前看到的行的状态。要计算这个或那个可能很复杂的布尔表达式,但不是这个…,选择大小写True/False很方便

演示代码:

Option Explicit

Function qq(s) : qq = """" & s & """" : End Function

Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject")
Dim oTS : Set oTS = oFS.OpenTextFile("..\data\41145072.txt")
Dim sLine, aParts, sKey, sVal, sCom, sCon, sProt
Do Until oTS.AtEndOfStream
   sLine  = oTS.ReadLine()
   aParts = Split(sLine, ":")
   If 1 = UBound(aParts) Then
        sKey   = Left(sLine, 3)
        sVal   = Trim(aParts(1))
'       WScript.Echo qq(sLine), qq(sVal)
        Select Case True
          Case sKey = "Com"
            sCom = sVal
          Case sKey = "Con"
            sCon = sVal
          Case sKey = "Pro" And sCon = "Fully Encrypted" And sVal = "Protection Off"
            WScript.Echo "****", sCom, sCon, sVal
        End Select
   Else
        WScript.Echo oTS.Line, qq(sLine), "Parse Error"
   End If
Loop
oTS.Close
输出:

cscript 41145072.vbs
**** Computer2 Fully Encrypted Protection Off

我过去不回答那些没有表现出OP努力的问题;然而,这个问题相当有趣

@echo off
setlocal EnableDelayedExpansion

for /F "delims=" %%a in (input.txt) do (
   set "line=%%a"
   for /F "tokens=1,2 delims=:" %%b in ("!line: =!") do (
      if "%%b" equ "ComputerName" set "ConversionStatus="
      if "%%b" equ "ConversionStatus" set "ProtectionStatus="
      set "%%b=%%c"
   )
   if "!ConversionStatus!+!ProtectionStatus!" equ "FullyEncrypted+ProtectionOff" (
      echo !ComputerName!
   )
)

具有两个正则表达式的powershell解决方案。 第一个将文件拆分为以计算机名开头的块

第二个使用命名的捕获组grep计算机名并检查条件

$InFile = ".\41145072.txt"

$Delimiter = 'Computer Name:'
$Escaped   = [regex]::Escape($Delimiter)
$Split     = "(?!^)(?=$Escaped)"
$Search = [RegEx]'(?smi)Computer Name:\s+(?<ComputerName>[0-9a-z_-]+).*Fully Encrypted\r\nProtection Status:\s+Protection Off'

(Get-Content $InFile -Raw) -split $Split | ForEach-Object {
    If ($_ -match $Search){
      $matches.ComputerName
    }
}
@回音 SETLOCAL 集合名称已找到= 设置convstatfullenc= 设置protstatof= 设置sourcedir=U:\sourcedir 设置文件名1=%sourcedir%\q4141572.txt 对于/f usebackqtokens=1,2*delims=:%a在%filename1%DO中 设置行处理= 如果/i%%a==计算机如果/i%%b==名称 SET namefound=%%c 设置convstatfullenc= 设置protstatof= 设置lineprocessed=Y 如果/i%%a==保护 设置protstatof= 如果/i%%b==状态如果/i%%c==保护关闭 设置protstatoff=Y 设置lineprocessed=Y 如果/i%%a==转换 设置convstatfullenc= 设置protstatof= 如果/i%%b==状态如果/i%%c==完全加密 设置convstatfullenc=Y 设置lineprocessed=Y 如果定义lineprocessed如果定义namefound如果定义convstatfullenc如果定义protstatoff 调用ECHO%%namefound%% 设置行处理= 如果未定义,则行处理 设置convstatfullenc= 设置protstatof= 后藤:EOF 您需要更改sourcedir的设置以适应您的环境

我使用了一个名为Q411141572.txt的文件,其中包含用于测试的数据

仅处理第一个单词,如果单词是computer和name,则会分配一个新的namefound,清除convstatfullenc和protstatoff两个标志,并将行标记为read。因此,每当遇到新的计算机名时,就会清除控制标志

如果遇到转换,则清除控制标志,并且仅当该行包含状态并在该行标记为已处理时完全加密时,才设置convstatfullenc

如果遇到保护,则只有当线路再次标记为已处理时,线路还包含状态和保护关闭时,才会设置protstatoff

如果行已处理且每个标志已设置,则每个条件都已满足,因此显示存储的名称。清除lineprocessed可确保在下一步清除两个控制标志

因此,如果找到了三条目标行中没有一条的行,则该行未设置为“已处理”,因此两个控制标志将被清除

如果找到转换行,则清除protstatoff并设置convstatfullenc

如果找到保护线,可设置protstatoff


设置这两个控制标志的唯一方法是保护线直接位于转换线之后,并通过完整测试。

让PowerShell脚本将数据导出为CSV而不是列表格式,然后你就可以简单地使用findstr了。有了CSV,我非常喜欢在查看数据时使用Excel/Google表格中的simple,因为你可以看到你的输出
如果你能发布任何代码来显示你的努力,我不会否决你的问题@嗯。。。您将来到一个网站,我们要求人们明确他们的问题,提供他们的代码并解释他们的努力。你没有做这些事。这并不是说网站不欢迎。。。是你在没有检查你应该有什么行为的情况下踩了进来。我们对提问有非常明确的指导方针。。。。你经历过吗?你确定你的问题符合我们的标准吗?因为如果没有,那么是的,我们会要求你跟随他们,你会在这个问题上得到否决票,同时否决票在你的帖子上,而不是反对你。你按小时收费吗?只是an的一个变体。我总是觉得这个语法1=UBoundaParts很混乱,设置值时,变量在左侧,赋值在右侧。为什么要在比较中切换呢?我真的很生气-对不起。谢谢,很抱歉最初没有包含任何代码。@AJH?据我所知,您还没有…Powershell提到了哪里?它已经标记了VBScript,批处理文件不需要第三个。@Lankymart今天心情不好?第一句提到powershell是文件的来源。当然,最好首先通过管道连接到另一个Powershell脚本/cmdlet来执行过滤。我不觉得我的剧本有问题。顺便说一句,你不是曾经错误地指责我没有提供解决方案吗?一点也不讨厌人们忽视指导方针/在合适的时候蔑视指导方针。你的答案很好问题在于问题,所以通过排除过程,答案不应该存在,但它确实存在。我错误地指责了你,你有消息来源吗?…我真的不记得了。你真的认为一个问题没有明确的问题,没有,而且他们实际上在使用什么,我知道你选择使用批处理文件,应该通过回答他们来鼓励你吗?@Lankymart:没有。是的。失业15年后,我需要一些东西来保持头脑活跃。没有足够的问题被张贴出来,以坚持遵守规则,所以我回答什么好玩我。当然-如果有人想让我做他们做不到的工作,那么他们要么会学到一些东西,这样我的努力就不会白费,要么他们会无意识地模仿我发布的内容而不理解它。如果这在将来的某个时候给他们的雇主带来了问题,那么这符合我的目的,因为雇主选择的雇员又回来咬他们了。把它看作是一个小马基雅维利主义。你可以通过提出问题、投票、,编辑和评论…你不需要对已经很严重的问题做出贡献。也许问题是你需要从批处理转移到更主流的东西,仅仅从你的个人资料来看。我无法想象现在对批处理程序员的需求有多大。@Lankymart:我更喜欢批处理文件标记中的区域性。参与者合作构建解决方案,而在更主流的领域,知名度高的投稿人及其追随者组成破坏性集团,连续投票否决非该集团成员提出的任何犯罪建议,如发布在线评论而非单独评论,或试图解决某个难以用英语表达问题的人发布的问题。用一种古老的动力不足的语言来解决问题让我觉得很有趣,就像用一台19世纪90年代的手动咖啡研磨机代替包装好的泥浆一样。