如何在查找cmd.exe或Powershell

时间:2015-10-15 18:11:44

标签: windows powershell batch-file cmd find

我有一个包含许多信息行的记录器文件。我想创建一个脚本,它找到包含" :: Directory"的所有行。只有当FOLLOWING行不是" ::调用subInACL" - >将所有找到的行放入文本文件中。

如果有时间戳,那就是新行。

特定帐户的SubinACL行(即xx1)将始终遵循" ::目录"线。所以我真正需要的是一个代码,用于检查" :: Directory"之后的行。行以" :: Calling"开头。如果是,请不要将其包含在输出中。

EX:如果记录器文件包含

10:03:11 AM::Directory \\aaa.yyy.com\ABC\Chem\xx1 created successfully.
10:03:11 AM::Calling subInACL (for ownership) with arguments:  /file \\025.aaa.yyy.com\Home10\Chem\xx1 /setowner=aaa\xx1
10:03:11 AM::Calling subInACL (for perms) with arguments:  /file \\025.aaa.yyy.com\Home10\Chem\xx1 /grant=aaa\xx1=C
10:03:12 AM::Directory \\025.aaa.yyy.com\Home10\Chem\xx1 given ACLs successfully.
10:16:15 AM::Directory \\aaa.yyy.com\ABC\Civil\xx2 created successfully.
10:16:48 AM::Directory \\aaa.yyy.com\ABC\Civil\xx3 created successfully.
10:16:48 AM::Directory \\aaa.yyy.com\ABC\Civil\xx4 created successfully.

我需要它来返回目录路径

10:16:15 AM::Directory \\aaa.yyy.com\ABC\Civil\xx2 created successfully.
10:16:48 AM::Directory \\aaa.yyy.com\ABC\Civil\xx3 created successfully.
10:16:48 AM::Directory \\aaa.yyy.com\ABC\Civil\xx4 created successfully.

因为他们没有" subInACL"也为他们的帐户创建。当一个" subinACL"不是为帐户创建的,这是一个错误,所以我需要查找未创建它的所有帐户。

我知道我可以使用

find "::Directory" logger.txt > found.txt

但这会返回ALL" ::目录"线。如何合并IF语句或正则表达式,只返回没有" ::调用subInACL"如下行。我可以直接在cmd行上执行此操作而无需调用批处理文件来运行吗?我知道我也可以使用Powershell ..如果这更容易吗?

我在Windows上使用cmd.exe。

2 个答案:

答案 0 :(得分:1)

@echo off
setlocal EnableDelayedExpansion

set "prevLine="
for /F "tokens=1-3*" %%a in (logger.txt) do (
   set "word=%%b"
   if "!word:~-9!" neq "::Calling" (
      if defined prevLine echo !prevLine!
      for %%x in ("%%c") do set "thisAcc=%%~Nx"
      if "!thisAcc!" equ "!badAcc!" (
         set "prevLine="
      ) else (
         set "prevLine=%%a %%b %%c %%d"
      )
      set "badAcc="
   ) else (
      set "prevLine="
      set "badAcc=!thisAcc!"
   )
)
if defined prevLine echo !prevLine!

输出:

10:16:15 AM::Directory \\aaa.yyy.com\ABC\Civil\xx2 created successfully.
10:16:48 AM::Directory \\aaa.yyy.com\ABC\Civil\xx3 created successfully.
10:16:48 AM::Directory \\aaa.yyy.com\ABC\Civil\xx4 created successfully.

答案 1 :(得分:0)

这在awk等工具中最容易处理,但是,只要付出足够的努力,就可以在cmd shell脚本中完成。 ENABLEDELAYEDEXPANSION是解决方案的关键。您需要能够在FOR循环中使用变量。

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET WAITING_FOR_NEXT_LINE=0

FOR /F "usebackq tokens=*" %%s IN (`TYPE log.txt`) DO (
    SET V=%%s
    SET LOOKING_FOR=!V:~11,12!

    IF !WAITING_FOR_NEXT_LINE! EQU 1 (
        IF "!V:~11,10!" NEQ "::Calling " (
            ECHO !LAST_LINE!
        )
    )

    SET WAITING_FOR_NEXT_LINE=0

    IF "!LOOKING_FOR!" EQU "::Directory " (
        SET LAST_LINE=%%s
        SET WAITING_FOR_NEXT_LINE=1
    )
)

IF %WAITING_FOR_NEXT_LINE% EQU 1 (ECHO %LAST_LINE%)

EXIT /B 0

你需要知道下一行应该推出前一行。同样重要的是,它需要在找到它后重置。

C:>logprocessor.bat
10:03:12 AM::Directory \\025.aaa.yyy.com\Home10\Chem\xx1 given ACLs successfully.
10:16:15 AM::Directory \\aaa.yyy.com\ABC\Civil\xx2 created successfully.
10:16:48 AM::Directory \\aaa.yyy.com\ABC\Civil\xx3 created successfully.
10:16:48 AM::Directory \\aaa.yyy.com\ABC\Civil\xx4 created successfully.

如果您想省略ACL行,请为该行的末尾添加一个测试。

IF !WAITING_FOR_NEXT_LINE! EQU 1 (
    IF "!V:~11,10!" NEQ "::Calling " (
        IF "!LAST_LINE:~-21!" EQU "created successfully." (
            ECHO !LAST_LINE!
        )
    )
)