我有一个包含许多信息行的记录器文件。我想创建一个脚本,它找到包含" :: 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。
答案 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!
)
)
)