我想创建一个windows批处理文件,主要包括3个任务:
1.它会要求用户输入:
Please Enter file name to search:
您必须在其中提供文件名,并根据文件名在某个指定位置搜索。
2.如果找到文件,它将再次在该文件中搜索某些模式(例如“错误”)。
3.从找到模式的行复制10行并将内容粘贴到另一个文件中。
例子:
您输入的文件名是:DemoFile 1.它将在指定位置搜索DemoFile.log。
2.如果找到上述文件,那么它将搜索一些模式(例如“错误”)。
3.Suppoese pattern Error was found in line #20 , then it would copy the contents from line #20 to line #30 to another file(MyDemoFile.txt).
看起来很复杂。无论如何需要帮助。
提前致谢:)
下面是我的代码片段,它提示用户输入文件名。
@ECHO OFF
*** Prompting user to enter the id*****
SET /P uname=Please enter the conversation id:
IF "%uname%"=="" GOTO Error
ECHO Entered Conversation Id : %uname%, Below Are the Log files related to this id:
FOR /F "tokens=* delims=" %%x in (a.txt) DO echo %%x
*** finding files based on that conversation id****
set LISTFOLDER=C:\Users\demo\Desktop\stats\test\a.txt -- passing parameter as conversation id
set FILESPATH=\\test\*.log
set DESTPATH=C:\Users\demo\Desktop\stats\test\check
for /f "tokens=*" %%i in ('dir /b ^"%LISTFOLDER%\*.txt^"') do (call :COPY_FILES "%LISTFOLDER%\%%i")
pause
exit
抬头。我不会只使用纯批处理和内置 Windows 工具来解决这个问题。 (实际上值得商榷。继续阅读!)我假设环境没有 100% 锁定,我们可以在第 3 部分使用稍微好一点的工具。
根据问题、示例代码和一些注释,我们想要提示输入文件名的子模式,并搜索一个目录中与该模式匹配的所有文件。
这里有一种提示方式,检查给定目录中是否存在任何文件,如果存在,则找到匹配的行。 (第 1 部分和第 2 部分)
@ECHO OFF
SETLOCAL
SET /P file=Please enter the thing you want to search in:
SET logfiles=some\path\to\%file%*.log
IF EXIST "%logfiles%" (
FINDSTR /I /P Error "%logfiles%" > "some\output\path\%file%_results.log"
) ELSE (
ECHO No matches for "%logfiles%" found.
EXIT /B 1
)
进入子目录留作练习。
第 3 部分,在匹配后获取 10 行比较棘手。我称之为“愚蠢的批处理技巧”可能是可能的。我现在想不出来。欢迎提出建议和修改。
但是,我个人会使用不同的工具来解决这个问题,假设我可以的话。我假设我们可以。
PowerShell 默认安装在从 Windows 7/Windows Server 2008R2 开始的许多 Windows 配置上。它的
Select-String
cmdlet 有一个 -Context
参数,可以控制包含多少行上下文。像下面这样的 cmdlet 是我要开始的框架。我故意 not 写入 cmdlet 中的输出文件,以便以后能够利用 PowerShell 的管道。这是一个您可以轻松更改的决定。
function Get-ErrorFromLog {
<#
.SYNOPSIS
Search through logs that match and extract the error lines and some context
.EXAMPLE
Get-ErrorFromLog -Log server
.PARAMETER Log
The base name of the log to search through. .log is automatically appended and we automatically search in SearchBase
.PARAMETER SearchBase
The directory to look in for logs
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='What log would you like to search in?')]
[string]$Log,
[Parameter(Mandatory=$False)]
[string]$SearchBase='some\path'
)
$logfiles = Get-ChildItem -Path $SearchBase -Filter ($Log + '*.log') -File -ErrorAction SilentlyContinue
if ($logfiles) {
$logfiles | Select-String -Pattern 'error' -Context 0,10
} else {
Write-Error "No items matchings `"$Log*.log`" exist in $SearchBase"
}
}
一些示例输出
PS D:\> Get-ErrorFromLog -Log does-not-exist
Get-ErrorFromLog : No items matchings "does-not-exist*.log" exist in some\path
At line:1 char:1
+ Get-ErrorFromLog -Log does-not-exist
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-ErrorFromLog
PS D:\> Get-ErrorFromLog -Log does-not-exist -SearchBase D:\temp\search
Get-ErrorFromLog : No items matchings "does-not-exist*.log" exist in D:\temp\search
At line:1 char:1
+ Get-ErrorFromLog -Log does-not-exist -SearchBase D:\temp\search
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-ErrorFromLog
PS D:\> # d:\temp\search\a.log exists, but has no errors
PS D:\> Get-ErrorFromLog -Log a -SearchBase D:\temp\search
PS D:\> Get-ErrorFromLog -Log b -SearchBase D:\temp\search
> temp\search\b.log:8:8 Error
temp\search\b.log:9:9 Attempting recovery
temp\search\b.log:10:10 Recovery in progress
temp\search\b.log:11:11 Recovery finished
temp\search\b.log:12:12 Nothing wrong at this time
temp\search\b.log:13:13 Nothing wrong at this time
temp\search\b.log:14:14 Nothing wrong at this time
temp\search\b.log:15:15 Nothing wrong at this time
temp\search\b.log:16:16 Nothing wrong at this time
temp\search\b.log:17:17 Nothing wrong at this time
temp\search\b.log:18:18 Nothing wrong at this time
> temp\search\b2.log:8:8 Error
temp\search\b2.log:9:9 Attempting recovery
temp\search\b2.log:10:10 Recovery in progress
temp\search\b2.log:11:11 Recovery finished
temp\search\b2.log:12:12 Nothing wrong at this time
temp\search\b2.log:13:13 Nothing wrong at this time
temp\search\b2.log:14:14 Nothing wrong at this time
temp\search\b2.log:15:15 Nothing wrong at this time
temp\search\b2.log:16:16 Nothing wrong at this time
temp\search\b2.log:17:17 Nothing wrong at this time
temp\search\b2.log:18:18 Nothing wrong at this time
进入子目录留作练习。在 PowerShell 中真的很容易。查看 Get-ChildItem.
的文档grep
工具,大多数现代版本的 grep 有一种方法可以控制匹配后打印的上下文数量。在我们的示例中,我们将使用类似以下的内容来代替 FINDSTR
命令。
grep --with-filename --after-context=10 --ignore-case error "%logfiles%" > "%file%_results.log"