我的批处理文件应该输出到包含dog.
例如,假设输入文件为:
dog.house, asdasd dog.dinner
dog.hello
结果应为:
dog.house
dog.dinner
dog.hello
到目前为止,我的批处理文件是:
for /F "tokens=*" %%a in ('findstr /c condor. temp.txt') do echo %%a >> resultado.txt
但是返回整行而不是包含“dog”的短语。 我无法理解批处理的工作原理。
答案 0 :(得分:2)
是的,for
循环很棘手。没有任何开关的for
在一行上逐字解析。 for /f
逐行循环,如果需要,使用标记作为单词。你需要的是两者的结合。
@echo off
for /f "delims=" %%I in ('findstr /i "dog\." temp.txt') do (
for %%a in (%%I) do (
echo %%a | findstr /i "dog\."
)
)
这会给你你期望的结果。
示例结果
C:\Users\me\Desktop>type temp.txt
dog.house, asdasd dog.dinner
dog.hello
C:\Users\me\Desktop>test.bat
dog.house
dog.dinner
dog.hello
答案 1 :(得分:2)
您可以在FOR命令上使用一个很好的教程。我最喜欢的是http://judago.webs.com/batchforloops.htm
只要文件不包含*
或?
个字符, rojo就有一个很好的解决方案。 FOR循环断开<space>
,<tab>
,,
,;
和=
处的“词组”。这是一个稍微高效的版本,通过FINDSTR的单次迭代管理所有“短语”。我还使用了奥术语法来禁用DELIMS和EOL,以便保留以;
开头的行。
@echo off
setlocal
cmd /c "for /f delims^=^ eol^= %%I in ('findstr /c:"dog." test.txt') do @for %%a in (%%I) do @echo %%a" | findstr /c:"dog." >resultado.txt
*
和?
限制可以通过放弃简单的FOR并使用搜索和替换来替换<line feed>
替换space
来解决,并通过FINDSTR回显结果。有批处理的语法。但它只会使解决方案变慢:(
我怀疑速度提升是否足够。你可以像rojo建议的那样下载和使用grep,或者你可以切换到更好的脚本语言,如VBScript,JScript或PowerShell。
修改强>
有时您无法将可执行文件下载到计算机上,并且您可能不习惯使用其他脚本语言。
我编写了一个名为REPL.BAT的混合批处理/ JScript实用程序,它执行正则表达式搜索和替换。它适用于所有现代Windows机器,不需要任何安装过程。只要REPL.BAT位于您当前的文件夹中,或者位于PATH中的某个位置,那么以下简单的行就能满足您的需求。它使用REPL.BAT将所有空格转换为换行符,然后将结果传递给FINDSTR。这个解决方案应该足够快。
repl.bat " " "\n" x <temp.txt | findstr /c:"dog." >resultado.txt
这是REPL.BAT实用程序。完整的文档嵌入在脚本中。
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment
::************ Documentation ***********
:::
:::REPL Search Replace [Options [SourceVar]]
:::REPL /?
:::
::: Performs a global search and replace operation on each line of input from
::: stdin and prints the result to stdout.
:::
::: Each parameter may be optionally enclosed by double quotes. The double
::: quotes are not considered part of the argument. The quotes are required
::: if the parameter contains a batch token delimiter like space, tab, comma,
::: semicolon. The quotes should also be used if the argument contains a
::: batch special character like &, |, etc. so that the special character
::: does not need to be escaped with ^.
:::
::: If called with a single argument of /? then prints help documentation
::: to stdout.
:::
::: Search - By default this is a case sensitive JScript (ECMA) regular
::: expression expressed as a string.
:::
::: JScript syntax documentation is available at
::: http://msdn.microsoft.com/en-us/library/ae5bf541(v=vs.80).aspx
:::
::: Replace - By default this is the string to be used as a replacement for
::: each found search expression. Full support is provided for
::: substituion patterns available to the JScript replace method.
::: A $ literal can be escaped as $$. An empty replacement string
::: must be represented as "".
:::
::: Replace substitution pattern syntax is documented at
::: http://msdn.microsoft.com/en-US/library/efy6s3e6(v=vs.80).aspx
:::
::: Options - An optional string of characters used to alter the behavior
::: of REPL. The option characters are case insensitive, and may
::: appear in any order.
:::
::: I - Makes the search case-insensitive.
:::
::: L - The Search is treated as a string literal instead of a
::: regular expression. Also, all $ found in Replace are
::: treated as $ literals.
:::
::: E - Search and Replace represent the name of environment
::: variables that contain the respective values. An undefined
::: variable is treated as an empty string.
:::
::: M - Multi-line mode. The entire contents of stdin is read and
::: processed in one pass instead of line by line. ^ anchors
::: the beginning of a line and $ anchors the end of a line.
:::
::: X - Enables extended substitution pattern syntax with support
::: for the following escape sequences:
:::
::: \\ - Backslash
::: \b - Backspace
::: \f - Formfeed
::: \n - Newline
::: \r - Carriage Return
::: \t - Horizontal Tab
::: \v - Vertical Tab
::: \xnn - Ascii (Latin 1) character expressed as 2 hex digits
::: \unnnn - Unicode character expressed as 4 hex digits
:::
::: Escape sequences are supported even when the L option is used.
:::
::: S - The source is read from an environment variable instead of
::: from stdin. The name of the source environment variable is
::: specified in the next argument after the option string.
:::
::************ Batch portion ***********
@echo off
if .%2 equ . (
if "%~1" equ "/?" (
findstr "^:::" "%~f0" | cscript //E:JScript //nologo "%~f0" "^:::" ""
exit /b 0
) else (
call :err "Insufficient arguments"
exit /b 1
)
)
echo(%~3|findstr /i "[^SMILEX]" >nul && (
call :err "Invalid option(s)"
exit /b 1
)
cscript //E:JScript //nologo "%~f0" %*
exit /b 0
:err
>&2 echo ERROR: %~1. Use REPL /? to get help.
exit /b
************* JScript portion **********/
var env=WScript.CreateObject("WScript.Shell").Environment("Process");
var args=WScript.Arguments;
var search=args.Item(0);
var replace=args.Item(1);
var options="g";
if (args.length>2) {
options+=args.Item(2).toLowerCase();
}
var multi=(options.indexOf("m")>=0);
var srcVar=(options.indexOf("s")>=0);
if (srcVar) {
options=options.replace(/s/g,"");
}
if (options.indexOf("e")>=0) {
options=options.replace(/e/g,"");
search=env(search);
replace=env(replace);
}
if (options.indexOf("l")>=0) {
options=options.replace(/l/g,"");
search=search.replace(/([.^$*+?()[{\\|])/g,"\\$1");
replace=replace.replace(/\$/g,"$$$$");
}
if (options.indexOf("x")>=0) {
options=options.replace(/x/g,"");
replace=replace.replace(/\\\\/g,"\\B");
replace=replace.replace(/\\b/g,"\b");
replace=replace.replace(/\\f/g,"\f");
replace=replace.replace(/\\n/g,"\n");
replace=replace.replace(/\\r/g,"\r");
replace=replace.replace(/\\t/g,"\t");
replace=replace.replace(/\\v/g,"\v");
replace=replace.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g,
function($0,$1,$2){
return String.fromCharCode(parseInt("0x"+$0.substring(2)));
}
);
replace=replace.replace(/\\B/g,"\\");
}
var search=new RegExp(search,options);
if (srcVar) {
WScript.Stdout.Write(env(args.Item(3)).replace(search,replace));
} else {
while (!WScript.StdIn.AtEndOfStream) {
if (multi) {
WScript.Stdout.Write(WScript.StdIn.ReadAll().replace(search,replace));
} else {
WScript.Stdout.WriteLine(WScript.StdIn.ReadLine().replace(search,replace));
}
}
}