我正在尝试编写一个批处理文件来处理包含以下记录的文件:
c:\SSSM\logs\CAP61.K10TEST.LOAD.log: 299 Rows successfully loaded.
c:\SSSM\logs\CAP61.K10TEST.LOAD.log: 0 Rows not loaded due to data errors.
c:\SSSM\logs\CAP63.K10TEST.LOAD.log: 232 Rows successfully loaded.
c:\SSSM\logs\CAP63.K10TEST.LOAD.log: 0 Rows not loaded due to data errors.
创建一个看起来像这样的分隔文件(中间没有空行):
CAP61-LOADED; 299
CAP61-NOT-LOADED; 0
CAP63-LOADED; 232
CAP63-NOT-LOADED; 0
目录和日志文件名可能会改变,所以我想我需要对表前缀(CAP,CFI等)进行某种搜索以提取5字节表名,然后格式化一种标签如果行包含“成功加载”而另一行包含“未加载”。我很感激您提供的任何帮助。
答案 0 :(得分:1)
@ECHO OFF
SETLOCAL
(
FOR /f "delims=" %%a IN (q21129289.txt) DO (
ECHO %%a|FIND /i "not loaded" >NUL
IF ERRORLEVEL 1 (SET "loaded=") ELSE (SET "loaded=-NOT")
FOR /f "tokens=2,3delims=:" %%c IN ("%%a") DO (
FOR /f "delims=." %%n IN ("%%~nc") DO CALL :showresult %%n %%d
)
)
)>newfile.txt
GOTO :EOF
:showresult
ECHO %1%loaded%-LOADED; %2
GOTO :eof
此批处理从文件q21129289.txt
读取并创建新文件newfile.txt
将主线括号化会导致输出重定向到文件; >
重新创建,>>
会追加。
首先,整行应用于%%a
。这会发送到FIND
,查找not loaded
(/i
表示不区分大小写)
如果未找到该字符串,则errorlevel
设置为非零,因此loaded
设置为空字符串。如果找到该字符串,errorlevel
设置为0,loaded
因此设置为-NOT
。
将%%a
作为字符串,我们查找由冒号分隔的第二个和第三个标记。它们适用于%%c
和%%d
(下一个元变量,按字母顺序排列),因此full-filename minus the drive
转到%%c
,第二个冒号后的整个字符串转到%%d
下一步是在%%c
中仅对文件名的名称部分提取相同的技巧。这整齐地处理了路径,并且我们希望第一个令牌给定其余.
的分隔符。这适用于%%n
CALL
然后调用子程序,提供所需的名字的第一部分和原始的第二次冒号后的剩余部分作为参数;例如
call :showresult CAP61 299 Rows successfully loaded.
子程序简单地将第一个参数(CAP61),loaded
的内容,字符串-LOADED;
和第一个字符串(299)中的第一个字符串串起来
当然输出会被重定向到输出文件。
答案 1 :(得分:1)
正则表达式的奇迹: - )
以下使用REPL.BAT - a hybrid JScript/batch utility that performs a regex search and replace on stdin and writes the result to stdout。 REPL.BAT应该在你当前的目录中,或者更好,在你的PATH中的某个地方。
type input.txt|repl ".*\\(.*?)\..*: *(\d*) .*? (not )?loaded.*" "$1-$3LOADED; $2"|repl "-not " "-NOT-" >output.txt
答案 2 :(得分:1)
关于拆分和字符串替换的练习
@echo off
setlocal enableextensions enabledelayedexpansion
set "successfully="
set "not=-NOT"
for /f "tokens=2,3 delims=:" %%a in (input.txt) do (
for /f "tokens=1 delims=." %%c in ("%%~na") do (
for /f "tokens=1,3 delims= " %%d in ("%%b") do echo %%c!%%e!-LOADED; %%d
)
)
endlocal
作为的行
c:\SSSM\logs\CAP61.K10TEST.LOAD.log: 299 Rows successfully loaded.
c:\SSSM\logs\CAP61.K10TEST.LOAD.log: 0 Rows not loaded due to data errors.
我们得到了
%%a = \SSSM\logs\CAP61.K10TEST.LOAD.log
%%b = 299 Rows successfully ... / 0 Rows not loaded ...
%%c = CAP61
%%d = 299 / 0
%%e = successfully / not
第一个for
分割冒号,将文件引用%%a
与信息数据%%b
从%%a
中的文件引用中,仅获取文件名并按点分割以获取%%c
中所需的部分。
根据%%b
中的信息数据,拆分空格以检索%%d
中的行数和%%e
中的状态
现在我们已经拥有了所有必需的信息,剩下的就是格式化输出。根据{{1}}的内容扩展两个定义的变量(not
和successfully
)以获得正确的输出。
答案 3 :(得分:0)
您可以使用awk
。从here下载
C:\> awk "{s=$2; gsub(/.*\\|\..*$/,\"\") ;print $0\" \"( (s>0) ?\"LOADED\":\"NOT-LOADED\" ) }" myFile.txt
CAP61 LOADED
CAP61 NOT-LOADED
CAP63 LOADED
CAP63 NOT-LOADED