findstr的命令行分析機(jī)制

2018-11-06 10:30 更新

來源:http://www.cn-dos.net/forum/viewthread.php?tid=21167&fpage=1&highlight=findstr

問題緣起于bsijl一篇關(guān)于findstr錯誤過濾的主題[1],當(dāng)時因為無法找到原因,所以只能推測 /g 開關(guān)存在某些問題。


    近日,因為編寫一個debuger代碼,再次使用了 findstr/g ,結(jié)果遇到了同樣的問題[2]。經(jīng)過仔細(xì)的測試[3]后,發(fā)現(xiàn)是 findstr 

    特殊的命令行分析機(jī)制所引起的問題。略述如下:


                                    

1、findstr不同于早期的find,它對參數(shù)的排列有一定的要求,即遵循開關(guān)(可省略)、字符串(使用/c開關(guān)時省略)、文件名(可通配、可多個、有輸入流時需省略)的順序。


                                    

2、開關(guān)可以使用引號,所以不能直接以與開關(guān)相同的關(guān)鍵字進(jìn)行搜索;文件名含空格時必須用引號。


3、搜索關(guān)鍵字的情況和表現(xiàn)就比較復(fù)雜,分述如下:

                                    

    3-1、無論是否使用開關(guān)/l或/r以及是否使用引號,關(guān)鍵字中的\都會成為轉(zhuǎn)義字符,所以\\將成為\,\"將使引號失去字符串界定作用;

                                    

    3-2、搜索關(guān)鍵字可加或不加引號,當(dāng)加引號時其中的\可能會再次轉(zhuǎn)義。使用開關(guān)/l和/r時的轉(zhuǎn)義結(jié)果可能會不同:當(dāng)使用/r時,所以"\\\\"將成為單個\,"\\"將使關(guān)鍵字為空;當(dāng)使用/l或均不使用時,"\\\\"和"\\"與單個\等價。

                                    3-3、如果關(guān)鍵字以單個\結(jié)尾,且無引號,則不會被轉(zhuǎn)義;


而 findstr/g出現(xiàn)的問題,應(yīng)該與上述內(nèi)容有關(guān),但其內(nèi)在機(jī)理仍無法透徹理解。不知各位有何高見?


     [1]批處理刪除XP輸入法問題!請dos高手解決

        http://www.cn-dos.net/forum/search.php?searchid=24472


        [2]Test of findstr/v/g



      Quote:

         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




          [3]Test of findstr

          CODE:  [Copy to clipboard]



           :: 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 ]





           Climbing

           金牌會員 


                      

           『第 2 樓』:  


            在我的XP上這個結(jié)果如何解釋?


             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: 搜索字符串太長。



無奈何

版主 


『第 3 樓』:  


     在我的 XP 下和 willsort 兄 3、的描述相同。這個惱人的結(jié)果不知道能不能確定是 

     FINDSTR 的 BUG ,請朋友們多試一下其它系統(tǒng)的情況??磥黻P(guān)鍵字中含有 “\” 

     字符應(yīng)該多加小心了。



3742668

版主 


『第 4 樓』:  


     唔,似乎只有當(dāng)\后面的字符為非字母和非數(shù)字的時候才會出錯。感覺microsoft準(zhǔn)備把findstr做成cmd下的正則表達(dá)式工具似的,但是又沒有考慮到與其他參數(shù)之間的兼容性,導(dǎo)致最后的結(jié)果是畫虎不成反類犬。

     另外在某些時候,findstr的查找字符串中包含中文時,需要加上/i參數(shù)才能避免錯誤,具體環(huán)境以及代碼已忘,或許findstr除了正則表達(dá)式方面的bug外還存在unicode與ascii轉(zhuǎn)換的bug。



willsort

版主 


『第 5 樓』:  


Re Ups:


另外一個問題:


     因為開關(guān)也允許引號,所以無法以 "/l" 或 "/r" 

     等與開關(guān)相同的文本串作為關(guān)鍵字匹配,下面的句式將會出錯:

                                      echo /l /r > test

                                      findstr /l "/r" test


不過,可以使用開關(guān) /c 來強(qiáng)制指定關(guān)鍵字:

                                      findstr /l /c:"/r" test

                                      findstr /l /c:/r test


還有一個方法,就是上文提到的 \ 了:

                                      findstr /l \/r test

                                     

此外,這個 \ 還可以讓我們的關(guān)鍵字中包含引號:

                                      echo /l /r >test

                                      echo "/r" >> test

                                      findstr /l \"/r\" test


最后,修訂和增補頂樓3-2中的一些描述:

                                      3-2、開關(guān)/r和開關(guān)/l相同,其后的關(guān)鍵字均可使用或不使用引號;使用引號時:

                                      3-2-1、"\"和"\\\"等價于引號和其后各個串所各自代表的多個關(guān)鍵字;

                                      

                              3-2-2、"\\\\\"和"\\\\\\\"等價于引號加\組成的關(guān)鍵字和其他多個關(guān)鍵字;

                                      3-2-3、"\\\\\\\\\"等價于引號加\\組成的關(guān)鍵字和其他多個關(guān)鍵字;

                                      3-2-4、"\ ","\\","\\\ ","\\\\\ 

                              ","\\\\\\","\\\\\\\ "等價于空;

                                      3-2-5、"\\ ","\\\\"等價于一個\;

                                      3-2-6、"\\\\ ","\\\\\\\\"等價于兩個\;

                                      3-2-7、"\\\\\\ "等價于三個\;

                                      3-2-8、"\\\\\\\\ "等價于四個\;


以上數(shù)據(jù)由以下方法測得,測試文件見[1][2],當(dāng)不使用/r開關(guān)與使用開關(guān)/l相同,;

                                      type test1.txt | findstr /r "test_key" 

                              test2.xt



                              [1] Test text of findstr - "test1.txt"



                                  Quote:

                                /l /r

                                "/l" 

                                " test1

                                \" test1

                                \\" test1

                                \\\" test1

                                \\\\" test1

                                \ test1

                                \\ test1

                                \\\ test1

                                \\\\ test1




                              [2] Test text of findstr - "test2.txt"



                                  Quote:

                                " test2

                                \" test2

                                \\" test2

                                \\\" test2

                                \\\\" test2

                                \ test2

                                \\ test2

                                \\\ test2

                                \\\\ test2




                              [ Last edited by willsort on 2006-6-11 at 18:25 ]




220110

版主 



『第 6 樓』:  





Quote:

                                        3-2、開關(guān)/r和開關(guān)/l相同,其后的關(guān)鍵字均可使用或不使用引號;使用引號時:

                                        3-2-1、"\"和"\\\"等價于引號和其后各個串所各自代表的多個關(guān)鍵字;

                                        

                                3-2-2、"\\\\\"和"\\\\\\\"等價于引號加\組成的關(guān)鍵字和其他多個關(guān)鍵字;

                                        3-2-3、"\\\\\\\\\"等價于引號加\\組成的關(guān)鍵字和其他多個關(guān)鍵字;

                                        3-2-4、"\ ","\\","\\\ ","\\\\\ 

                                ","\\\\\\","\\\\\\\ "等價于空;

                                        3-2-5、"\\ ","\\\\"等價于一個\;

                                        3-2-6、"\\\\ ","\\\\\\\\"等價于兩個\;

                                        3-2-7、"\\\\\\ "等價于三個\;

                                        3-2-8、"\\\\\\\\ "等價于四個\;




我早前也發(fā)現(xiàn)這規(guī)律存在路徑名上,只是沒深入研究,沒敢貼上來.

我是從"dir .\",  " dir ..\" 開始,大家不妨測試下.



willsort

版主 


狀態(tài) 離線 『第 7 樓』:  


Re 220110:


UNC 路徑名中 \ 的解析與 findstr 

關(guān)鍵字是不同的,它只有界定目錄的作用,而沒有轉(zhuǎn)義字符的作用。



另外,findstr /v ^%var%$ test.txt 語句中,如果test.txt最后一行就是要匹配的%var%,且該行不為空,則不能過濾最后一行的內(nèi)容,似乎是分行標(biāo)志識別出了錯


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號