|
willsort
元老会员
         Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『楼 主』:
[讨论]findstr的命令行分析机制
使用 LLM 解释/回答一下
To All:
问题缘起于bsijl一篇关于findstr错误过滤的主题,当时因为无法找到原因,所以只能推测 /g 开关存在某些问题。
近日,因为编写一个debuger代码,再次使用了 findstr/g ,结果遇到了同样的问题。经过仔细的测试后,发现是 findstr 特殊的命令行分析机制所引起的问题。略述如下:
1、findstr不同于早期的find,它对参数的排列有一定的要求,即遵循开关(可省略)、字符串(使用/c开关时省略)、文件名(可通配、可多个、有输入流时需省略)的顺序。
2、开关可以使用引号, 所以不能直接以与开关相同的关键字进行搜索;文件名含空格时必须用引号。
3、搜索关键字的情况和表现就比较复杂,分述如下:
3-1、无论是否使用开关/l或/r以及是否使用引号,关键字中的\都会成为转义字符,所以\\将成为\,\"将使引号失去字符串界定作用;
3-2、 搜索关键字可加或不加引号,当加引号时其中的\可能会再次转义。使用开关/l和/r时的转义结果可能会不同:当使用/r时,所以"\\\\"将成为单个\,"\\"将使关键字为空;当使用/l或均不使用时,"\\\\"和"\\"与单个\等价。
3-3、如果关键字以单个\结尾,且无引号,则不会被转义;
而 findstr/g出现的问题,应该与上述内容有关,但其内在机理仍无法透彻理解。不知各位有何高见?
批处理删除XP输入法问题!请dos高手解决
http://www.cn-dos.net/forum/search.php?searchid=24472
Test of findstr/v/g
E:\Batch\Test>set > envar.out
E:\Batch\Test>findstr /v /g:envar.out envar.out
LOGONSERVER=\\Test
ProgramFiles=C:\Program Files
E:\Batch\Test>findstr /v /i /g:envar.out envar.out
LOGONSERVER=\\Test
Test of findstr
:: Test of findstr
:: Will Sort - 2006-06-10 - CMDWinXP
@echo off
cls&echo ---- "set>_tfs1.tmp & findstr /v /g:_tfs1.tmp _tfs1.tmp"
set>_tfs1.tmp & findstr /v /g:_tfs1.tmp _tfs1.tmp
pause
echo ---- "findstr /v /i /g:_tfs1.tmp _tfs1.tmp"
findstr /v /i /g:_tfs1.tmp _tfs1.tmp
pause
echo ---- "sort /r _tfs1.tmp > _tfs2.tmp & findstr /v /g:_tfs1.tmp _tfs2.tmp"
sort /r _tfs1.tmp > _tfs2.tmp & findstr /v /g:_tfs1.tmp _tfs2.tmp
pause
echo ---- "set|findstr /v /g:_tfs1.tmp"
set|findstr /v /g:_tfs1.tmp
pause
cls&echo ---- "dir C:\ /w > _tfs2.tmp & findstr /v /g:_tfs2.tmp _tfs2.tmp"
dir C:\ /w > _tfs2.tmp & findstr /v /g:_tfs2.tmp _tfs2.tmp
pause
echo ---- "echo :\ > _tfs2.tmp & findstr /v /g:_tfs2.tmp _tfs2.tmp"
echo :\ > _tfs2.tmp & findstr /v /g:_tfs2.tmp _tfs2.tmp
pause
cls&echo ---- "findstr /g:_tfs1.tmp _tfs1.tmp>_tfs2.tmp & fc _tfs1.tmp _tfs2.tmp"
findstr /g:_tfs1.tmp _tfs1.tmp>_tfs2.tmp & fc _tfs1.tmp _tfs2.tmp
pause
cls&echo ---- "set|findstr /r "\\\\ \\\\""
set|findstr /r "\\\\ \\\\"
pause
echo ---- "set|findstr /l "\\\\ \\\\""
set|findstr /l "\\\\ \\\\"
pause
cls&echo ---- "echo _tfs1_tmp > _tfs1.tmp & findstr "/l" "_tfs1.tmp" "_tfs1.tmp""
echo _tfs1_tmp >> _tfs1.tmp & findstr "_tfs1.tmp" "_tfs1.tmp"
pause
del _tfs?.tmp
Last edited by willsort on 2006-6-11 at 18:38 ]
To All:
The problem originated from a topic by bsijl about incorrect filtering with findstr . At that time, since the cause couldn't be found, we could only speculate that there were certain issues with the /g switch.
Recently, when writing a debugger code, I used findstr/g again and encountered the same problem . After careful testing , it was found that the problem was caused by the special command-line parsing mechanism of findstr. Briefly described as follows:
1. Unlike the early find, findstr has certain requirements for the arrangement of parameters, that is, it follows the order of switches (can be omitted), strings (omitted when using the /c switch), and file names (can be wildcards, can be multiple, and need to be omitted when there is an input stream).
2. Switches can use quotes, so you can't directly search with keywords the same as switches; file names with spaces must use quotes.
3. The situation and performance of search keywords are relatively complicated, described as follows:
3-1. Whether using the /l or /r switch or using quotes, \ in the keyword will become an escape character, so \\ will become \, and \" will make the quote lose the string delimiting function;
3-2. Search keywords can be with or without quotes. When with quotes, \ in them may be escaped again. The escape results when using /l and /r switches may be different: when using /r, so "\\\\" will become a single \, and "\\" will make the keyword empty; when using /l or neither, "\\\\" and "\\" are equivalent to a single \.
3-3. If the keyword ends with a single \ and has no quotes, it will not be escaped;
And the problem with findstr/g should be related to the above content, but the internal mechanism is still not thoroughly understood. I wonder what everyone's opinions are?
Batch processing to delete XP input method problem! Please DOS experts solve
http://www.cn-dos.net/forum/search.php?searchid=24472
Test of findstr/v/g
E:\Batch\Test>set > envar.out
E:\Batch\Test>findstr /v /g:envar.out envar.out
LOGONSERVER=\\Test
ProgramFiles=C:\Program Files
E:\Batch\Test>findstr /v /i /g:envar.out envar.out
LOGONSERVER=\\Test
Test of findstr
:: Test of findstr
:: Will Sort - 2006-06-10 - CMDWinXP
@echo off
cls&echo ---- "set>_tfs1.tmp & findstr /v /g:_tfs1.tmp _tfs1.tmp"
set>_tfs1.tmp & findstr /v /g:_tfs1.tmp _tfs1.tmp
pause
echo ---- "findstr /v /i /g:_tfs1.tmp _tfs1.tmp"
findstr /v /i /g:_tfs1.tmp _tfs1.tmp
pause
echo ---- "sort /r _tfs1.tmp > _tfs2.tmp & findstr /v /g:_tfs1.tmp _tfs2.tmp"
sort /r _tfs1.tmp > _tfs2.tmp & findstr /v /g:_tfs1.tmp _tfs2.tmp
pause
echo ---- "set|findstr /v /g:_tfs1.tmp"
set|findstr /v /g:_tfs1.tmp
pause
cls&echo ---- "dir C:\ /w > _tfs2.tmp & findstr /v /g:_tfs2.tmp _tfs2.tmp"
dir C:\ /w > _tfs2.tmp & findstr /v /g:_tfs2.tmp _tfs2.tmp
pause
echo ---- "echo :\ > _tfs2.tmp & findstr /v /g:_tfs2.tmp _tfs2.tmp"
echo :\ > _tfs2.tmp & findstr /v /g:_tfs2.tmp _tfs2.tmp
pause
cls&echo ---- "findstr /g:_tfs1.tmp _tfs1.tmp>_tfs2.tmp & fc _tfs1.tmp _tfs2.tmp"
findstr /g:_tfs1.tmp _tfs1.tmp>_tfs2.tmp & fc _tfs1.tmp _tfs2.tmp
pause
cls&echo ---- "set|findstr /r "\\\\ \\\\""
set|findstr /r "\\\\ \\\\"
pause
echo ---- "set|findstr /l "\\\\ \\\\""
set|findstr /l "\\\\ \\\\"
pause
cls&echo ---- "echo _tfs1_tmp > _tfs1.tmp & findstr "/l" "_tfs1.tmp" "_tfs1.tmp""
echo _tfs1_tmp >> _tfs1.tmp & findstr "_tfs1.tmp" "_tfs1.tmp"
pause
del _tfs?.tmp
Last edited by willsort on 2006-6-11 at 18:38 ]
|

※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2006-6-10 22:46 |
|
|
Climbing
铂金会员
       网络独行侠
积分 6962
发帖 2753
注册 2003-4-16 来自 河北保定
状态 离线
|
『第 2 楼』:
使用 LLM 解释/回答一下
在我的XP上这个结果如何解释?
d:\work>findstr /v /g:envar.out envar.out
FINDSTR: 搜索字符串太长。
d:\work>findstr /v /g:envar.out envar.out
FINDSTR: 搜索字符串太长。
d:\work>findstr /v /g:envar.out
FINDSTR: 搜索字符串太长。
How to explain this result on my XP?
d:\work>findstr /v /g:envar.out envar.out
FINDSTR: The search string is too long.
d:\work>findstr /v /g:envar.out envar.out
FINDSTR: The search string is too long.
d:\work>findstr /v /g:envar.out
FINDSTR: The search string is too long.
|

偶只喜欢回答那些标题和描述都很清晰的帖子!
如想解决问题,请认真学习“这个帖子”和“这个帖子”并努力遵守,如果可能,请告诉更多的人!
|
|
2006-6-11 01:18 |
|
|
无奈何
荣誉版主
      
积分 1338
发帖 356
注册 2005-7-15
状态 离线
|
『第 3 楼』:
使用 LLM 解释/回答一下
在我的 XP 下和 willsort 兄 3、的描述相同。这个恼人的结果不知道能不能确定是 FINDSTR 的 BUG ,请朋友们多试一下其它系统的情况。看来关键字中含有 “\” 字符应该多加小心了。
Under my XP, it is the same as the description of brother willsort 3. I don't know if this annoying result can confirm that it is a bug of FINDSTR. Please friends try the situation of other systems more. It seems that we should be more careful when the keyword contains the "\" character.
|

☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul
|
|
2006-6-11 03:02 |
|
|
3742668
荣誉版主
      
积分 2013
发帖 718
注册 2006-2-18
状态 离线
|
『第 4 楼』:
使用 LLM 解释/回答一下
唔,似乎只有当\后面的字符为非字母和非数字的时候才会出错。感觉microsoft准备把findstr做成cmd下的正则表达式工具似的,但是又没有考虑到与其他参数之间的兼容性,导致最后的结果是画虎不成反类犬。
另外在某些时候,findstr的查找字符串中包含中文时,需要加上/i参数才能避免错误,具体环境以及代码已忘,或许findstr除了正则表达式方面的bug外还存在unicode与ascii转换的bug。
Well, it seems that an error occurs only when the character following \ is neither a letter nor a digit. It feels like Microsoft is trying to make findstr a regular expression tool under cmd, but it didn't consider compatibility with other parameters, resulting in the final result being a botched job.
Also, in some cases, when the search string of findstr contains Chinese, the /i parameter needs to be added to avoid errors. The specific environment and code are forgotten. Maybe findstr has bugs in Unicode and ASCII conversion in addition to regular expression issues.
|
|
2006-6-11 14:43 |
|
|
willsort
元老会员
         Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第 5 楼』:
使用 LLM 解释/回答一下
Re Ups:
另外一个问题:
因为开关也允许引号,所以无法以 "/l" 或 "/r" 等与开关相同的文本串作为关键字匹配,下面的句式将会出错:
echo /l /r > test
findstr /l "/r" test
不过,可以使用开关 /c 来强制指定关键字:
findstr /l /c:"/r" test
findstr /l /c:/r test
还有一个方法,就是上文提到的 \ 了:
findstr /l \/r test
此外,这个 \ 还可以让我们的关键字中包含引号:
echo /l /r >test
echo "/r" >> test
findstr /l \"/r\" test
最后,修订和增补顶楼3-2中的一些描述:
3-2、开关/r和开关/l相同,其后的关键字均可使用或不使用引号;使用引号时:
3-2-1、"\"和"\\\"等价于引号和其后各个串所各自代表的多个关键字;
3-2-2、"\\\\\"和"\\\\\\\"等价于引号加\组成的关键字和其他多个关键字;
3-2-3、"\\\\\\\\\"等价于引号加\\组成的关键字和其他多个关键字;
3-2-4、"\ ","\\","\\\ ","\\\\\ ","\\\\\\","\\\\\\\ "等价于空;
3-2-5、"\\ ","\\\\"等价于一个\;
3-2-6、"\\\\ ","\\\\\\\\"等价于两个\;
3-2-7、"\\\\\\ "等价于三个\;
3-2-8、"\\\\\\\\ "等价于四个\;
以上数据由以下方法测得,测试文件见,当不使用/r开关与使用开关/l相同,;
type test1.txt | findstr /r "test_key" test2.xt
Test text of findstr - "test1.txt"
/l /r
"/l"
" test1
\" test1
\\" test1
\\\" test1
\\\\" test1
\ test1
\\ test1
\\\ test1
\\\\ test1
Test text of findstr - "test2.txt"
" test2
\" test2
\\" test2
\\\" test2
\\\\" test2
\ test2
\\ test2
\\\ test2
\\\\ test2
Last edited by willsort on 2006-6-11 at 18:25 ]
Re Ups:
Another question:
Because the switch also allows quotes, it is impossible to match keywords with the same text strings as the switches such as "/l" or "/r". The following sentence pattern will go wrong:
echo /l /r > test
findstr /l "/r" test
However, you can use the switch /c to force the designation of the keyword:
findstr /l /c:"/r" test
findstr /l /c:/r test
There is another method, which is the \ mentioned above:
findstr /l \/r test
In addition, this \ can also let our keywords contain quotes:
echo /l /r >test
echo "/r" >> test
findstr /l \"/r\" test
Finally, revise and supplement some descriptions in the top floor 3-2:
3-2. The switch /r is the same as the switch /l, and the keywords after it can use or not use quotes; when using quotes:
3-2-1. "\" and "\"\" are equivalent to the quotes and each of the subsequent strings representing multiple keywords;
3-2-2. "\"\"\" and "\"\"\"\" are equivalent to the keyword composed of quotes plus \ and other multiple keywords;
3-2-3. "\"\"\"\" is equivalent to the keyword composed of quotes plus \\ and other multiple keywords;
3-2-4. "\ ", "\\", "\\ ", "\\\ ", "\\\\", "\\\\\ " are equivalent to empty;
3-2-5. "\\ ", "\\\\" are equivalent to one \;
3-2-6. "\\\\ ", "\\\\\\\\" are equivalent to two \;
3-2-7. "\\\\\ " are equivalent to three \;
3-2-8. "\\\\\\\ " are equivalent to four \;
The above data are measured by the following method. The test files are see . When not using the /r switch, it is the same as using the /l switch,;
type test1.txt | findstr /r "test_key" test2.xt
Test text of findstr - "test1.txt"
/l /r
"/l"
" test1
\" test1
\\" test1
\\\" test1
\\\\" test1
\ test1
\\ test1
\\\ test1
\\\\ test1
Test text of findstr - "test2.txt"
" test2
\" test2
\\" test2
\\\" test2
\\\\" test2
\ test2
\\ test2
\\\ test2
\\\\ test2
Last edited by willsort on 2006-6-11 at 18:25 ]
|

※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2006-6-11 18:24 |
|
|
220110
荣誉版主
      
积分 718
发帖 313
注册 2005-9-26
状态 离线
|
『第 6 楼』:
使用 LLM 解释/回答一下
3-2、开关/r和开关/l相同,其后的关键字均可使用或不使用引号;使用引号时:
3-2-1、"\"和"\\\"等价于引号和其后各个串所各自代表的多个关键字;
3-2-2、"\\\\\"和"\\\\\\\"等价于引号加\组成的关键字和其他多个关键字;
3-2-3、"\\\\\\\\\"等价于引号加\\组成的关键字和其他多个关键字;
3-2-4、"\ ","\\","\\\ ","\\\\\ ","\\\\\\","\\\\\\\ "等价于空;
3-2-5、"\\ ","\\\\"等价于一个\;
3-2-6、"\\\\ ","\\\\\\\\"等价于两个\;
3-2-7、"\\\\\\ "等价于三个\;
3-2-8、"\\\\\\\\ "等价于四个\;
我早前也发现这规律存在路径名上,只是没深入研究,没敢贴上来.
我是从"dir .\", " dir ..\" 开始,大家不妨测试下.
3-2. The switches /r and /l are the same. The keywords that follow can use or not use quotes; when using quotes:
3-2-1. "\" and "\"\" are equivalent to the quote and each of the multiple keywords represented by each subsequent string;
3-2-2. "\"\"\" and "\"\"\"\" are equivalent to the keyword composed of quote plus \ and other multiple keywords;
3-2-3. "\"\"\"\"\" is equivalent to the keyword composed of quote plus \ and other multiple keywords;
3-2-4. "\ ", "\\", "\\\ ", "\\\\\ ", "\\\\", "\\\\\ " are equivalent to empty;
3-2-5. "\\ ", "\\\\" are equivalent to one \;
3-2-6. "\\\\ ", "\\\\\\\\" are equivalent to two \;
3-2-7. "\\\\\ " is equivalent to three \;
3-2-8. "\\\\\\\ " is equivalent to four \;
I also discovered this pattern earlier in pathnames, but I didn't study it deeply and didn't dare to post it.
I started from "dir .\" and " dir ..\", you might as well test it.
|
|
2006-6-17 21:07 |
|
|
willsort
元老会员
         Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第 7 楼』:
使用 LLM 解释/回答一下
Re 220110:
UNC 路径名中 \ 的解析与 findstr 关键字是不同的,它只有界定目录的作用,而没有转义字符的作用。
Re 220110:
The parsing of \ in the UNC pathname is different from the findstr keyword. It only has the function of delimiting directories and has no function of escape characters.
|

※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2006-6-18 18:19 |
|
|
jackerloo2009
新手上路

积分 1
发帖 1
注册 2009-5-19
状态 离线
|
『第 8 楼』:
使用 LLM 解释/回答一下
echo 王志慧|findstr /i ".*净"
加/i 仍然是个错误
还有对于/l参数仍不明了
findstr /v /x /i /g:B.txt A.txt
findstr /v /x /i /g:A.txt B.txt
我曾经比较过两个文本,里面都是邮件地址,结果不加/l的话结果中出来了一个共同点
两个文本中都有这个地址 p*.tournois@chello.fr
但比较不同后的结果仍然还是有这个地址。但是加了/l后避免了,对于这个/l按字使用搜索字符串,如何理解?所有的都变成普通字符逐字比较?
echo 王志慧|findstr /i ".*净"
Still an error with /i
Also, still unclear about the /l parameter
findstr /v /x /i /g:B.txt A.txt
findstr /v /x /i /g:A.txt B.txt
I once compared two texts, both containing email addresses. Without /l, a common point appeared in the result
Both texts have this address p*.tournois@chello.fr
But the result after comparing differences still had this address. But with /l, it was avoided. How to understand using /l to search the string character by character? All become ordinary characters for literal comparison?
|
|
2009-6-27 00:18 |
|
|
echoair
新手上路

积分 8
发帖 33
注册 2009-11-10
状态 离线
|
『第 9 楼』:
使用 LLM 解释/回答一下
希望大家能把findstr的基本用法系统做个总结…
I hope everyone can systematically summarize the basic usage of findstr...
|
|
2009-11-11 13:04 |
|
|
hongcheng668
新手上路

积分 10
发帖 9
注册 2009-10-17
状态 离线
|
|
2009-11-16 15:43 |
|
|
hongcheng668
新手上路

积分 10
发帖 9
注册 2009-10-17
状态 离线
|
|
2009-11-16 15:43 |
|
|
hongcheng668
新手上路

积分 10
发帖 9
注册 2009-10-17
状态 离线
|
|
2009-11-16 15:43 |
|