- 1. 動(dòng)感大挪移(利用手機(jī)GPRS無線上網(wǎng)工具) 綠色免費(fèi)版
- 2. 50個(gè)經(jīng)典BAT(批處理)實(shí)例
- 3. BAT解碼器(BAT解密器) 綠色版
- 4. sql綜合利用工具
- 5. adsl自動(dòng)撥號(hào)批處理
- 6. 批處理 for 語法精通
- 7. 戰(zhàn)地3(Battlefield 3)十一項(xiàng)修改器 1.02下載
- 8. 10個(gè)系統(tǒng)優(yōu)化的批處理(bat)文件
- 9. 批處理常用命令
- 10. 電池監(jiān)視桌面工具(Battery Monitor ) 1.6綠色版
批處理(bat)利用set p與重定向輸入分行獲取文本內(nèi)容
起因是前幾天的某個(gè)帖子中看到 cmd<1.txt 的用法,原以為1.txt 中的 pause 之所以被跳過是因?yàn)閳?zhí)行完后馬上接收到了一個(gè)回車符,于是我把1.txt 中的所有 pause 都改成 pause&rem ,并去除所有回車符進(jìn)行試驗(yàn),下為去除回車符的代碼:
1. | @echo off&setlocal enabledelayedexpansion |
2. | set hh=^ |
3. | |
4. | |
5. | ::獲取換行符 |
6. | for %%a in ( |
7. | "@echo off" "pause&rem" "echo abc" "pause&rem" |
8. | ) do set str=!str!!hh!%%~a |
9. | echo !str:~2!>3.txt |
10. | ::只用換行符斷行 |
11. | cmd<3.txt |
12. | echo; |
13. | echo ________end________ |
14. | Pause |
假設(shè)修改后 1.txt內(nèi)容如下(測(cè)試時(shí),此文本中不存在回車符):
1. | @echo off |
2. | pause&rem |
3. | echo abc |
4. | pause&rem |
結(jié)果仍然沒有等待用戶輸入,并且還吞掉了下一行 echo 的第一個(gè)字符,導(dǎo)致 cmd 顯示:
1. | 請(qǐng)按任意鍵繼續(xù). . . |
2. | 'cho' 不是內(nèi)部或外部命令,也不是可運(yùn)行的程序 |
3. | 或批處理文件。 |
4. | 請(qǐng)按任意鍵繼續(xù). . . |
對(duì)此感到非常疑惑,百思不得其解之下去請(qǐng)教寒夜版主,他問我 pause 等待的是什么輸入,我才忽然醒悟,原來 pause 等待的是“任意鍵”,也就是說,它把 echo 的 e 當(dāng)作用戶輸入給接收了(因?yàn)樾心┑?0D 0A被 cmd 接收了,所以 pause 接收的第一個(gè)字符就是下一行的首字符 e),因此這里用 pause 無法實(shí)現(xiàn)暫停的效果,這就推翻了我原來的認(rèn)識(shí),證明等待用戶輸入的命令并不是以回車符作為終止輸入的信號(hào)。
進(jìn)一步思考一下,眾所周知, set /p 首行=<1.txt 能獲取 1.txt 第一行,那么對(duì)含有大量 set /p 的語塊進(jìn)行重定向,又是什么結(jié)果呢?
1. | @echo off |
2. | (for /l %%a in (1 1 10) do set /p .%%a=)<%0 |
3. | set. |
4. | pause |
可以看到,通過 set /p 配合重定向,能夠把文本每一行都設(shè)為變量值,這是全新的技巧,更重要的是,這是一種全新的遍歷文本的方式,它相當(dāng)于不跳過空行的 for until ,這與 for /f 的skip 參數(shù)相映成趣,而且還對(duì)特殊字符有極佳的兼容性。不過有得必有失,使用 set /p 賦值時(shí),變量長(zhǎng)度不能超過 1024 字節(jié),所以局限了這個(gè)技巧的適用范圍。
激動(dòng)之余,又產(chǎn)生了兩個(gè)疑惑:
1、set /p 是以什么為依據(jù)斷行
2、當(dāng)循環(huán)數(shù)大于文本行數(shù)時(shí),為什么沒有停頓下來等待用戶輸入
和寒夜版主一起做了幾個(gè)試驗(yàn),證明無論是單純的 0D 回車符或者 0A 換行符都無法實(shí)現(xiàn)平時(shí)在 cmd 窗口中敲回車結(jié)束 set /p 輸入的效果,必須出現(xiàn)連續(xù)的一組 0D 0A 才能夠終止對(duì)一個(gè) set /p 的輸入。關(guān)于終止 set /p 輸入的“特征碼”,25 樓的 mxxcgzxxx 提出了更合理的猜想:0D 0A 和 0A 0D 這兩種組合都能起到終止 set /p 輸入的作用。
(25樓鏈接:
http://bbs.bathome.net/viewthread.php?tid=13327&page=2&fromuid=30406#pid86638)
而第二個(gè)問題,繞了半天彎子終于得到一個(gè)比較合理的猜測(cè):當(dāng)重定向的輸入被前面執(zhí)行的命令取用完的時(shí)候,剩下的就是從空設(shè)備的輸入,也就是 set /p .5=
1. | (set /p .a= |
2. | set /p .b=)<只有一行的文件.txt |
3. | set.[/code]其作用相當(dāng)于:[code]set /p .a=<只有一行的文件.txt |
4. | ::取首行 |
5. | set /p .b=<nul |
6. | ::從空設(shè)備獲取輸入,等于無輸入 |
7. | set. |
8. | ::顯示以.開頭的變量 |
通過這個(gè)猜測(cè)和其他一些命令接收重定向輸入時(shí)表現(xiàn)出的特性衍生出一個(gè)推測(cè),那就是 cmd 在接受重定向輸入到命令的時(shí)候,也許是一個(gè)字符一個(gè)字符順序傳遞給語塊\語句的,那些能夠接受重定向輸入的命令會(huì)自發(fā)地從中獲取輸入,直到命令自行關(guān)閉輸入句柄為止。
這可以理解為cmd中出現(xiàn)重定向輸入的時(shí)候,輸入中的字符在排隊(duì)等候被命令依次提走,一直到無字符可提的時(shí)候,重定向輸入的來源就成為了一個(gè)空設(shè)備 nul。
好比一個(gè)旅行團(tuán)在打車,出現(xiàn)愿意載客的出租車時(shí),隊(duì)伍就有序地依次上車,一輛車客滿后就再等下一輛(旅行團(tuán)并不知道當(dāng)前這輛車何時(shí)客滿,他們只需要機(jī)械地讓排頭的人上車、直到司機(jī)喊停為止),最終所有人都打車走光,這時(shí)候新來的出租車就找不到客人了,所以空車離開時(shí)當(dāng)然還是空車。
當(dāng)然有些命令是以任意合法字符或者固定字符來判定何時(shí)結(jié)束輸入的,比如choice、set /p和pause,這就很有利用的價(jià)值。
此處僅以 set /p 舉幾個(gè)例子:
1. | @echo off |
2. | set /p line=要獲取的行所在行數(shù): |
3. | (for /l %%a in (1 1 %line%) do set /p 內(nèi)容=)<a.txt |
4. | set 內(nèi)容 |
5. | ::獲取指定行內(nèi)容的新方法,由于無需遍歷整個(gè)文本,要獲取的行位置靠前的情況下有很大優(yōu)勢(shì) |
1. | @echo off |
2. | (for /l %%a in (1 1 100) do set /p .%%a=)<%0 |
3. | |
4. | ::不跳過空行賦值,但是 tmplinshi 版主的測(cè)試結(jié)果標(biāo)明這中方法比常規(guī)辦法稍慢,它只在某些場(chǎng)合有優(yōu)勢(shì)。 |
(5樓鏈接:
http://bbs.bathome.net/viewthread.php?tid=13327&page=1&fromuid=30406#pid86516)
1. | @echo off&setlocal enabledelayedexpansion |
2. | |
3. | (for /l %%a in (1 1 5) do ( |
4. | if not defined .!n! set /a n+=1 |
5. | set /p .!n!= |
6. | ))<%0 |
7. | ::當(dāng)然也同樣可以跳過空行只將前N行賦值 |
8. | |
9. | @echo off |
10. | (for /l %%a in (1 1 7) do ( |
11. | pause |
12. | set /p echo= |
13. | echo !echo! |
14. | )<%0 |
15. | ::去除每行行首第一個(gè)任意字符的另一種方法,如果不計(jì)較效率的話,用choice可以去除指定字符 |
1. | @echo off |
2. | (for /l %%a in (1 2 7) do ( |
3. | set /a a=1,b=2 |
4. | set /p a= |
5. | set /p b= |
6. | if !a!==!b! echo 相等 |
7. | )<%0 |
8. | ::以兩行為周期判斷其內(nèi)容是否相等,這比起老方法省下了許多麻煩,比如無需用 setlocal、endlocal 來兼容特殊字符 |
1. | @echo off |
2. | (for %%a in ( |
3. | 1-關(guān)回顯 2-for循環(huán) 3-循環(huán)內(nèi)容 4-do 4-設(shè)變量 5-輸入 6-查看變量 7-注釋 |
4. | ) do ( |
5. | set /p .%%a= |
6. | ))<%0 |
7. | set. |
8. | ::可以通過無參數(shù)的for來循環(huán),實(shí)現(xiàn)了以往無法實(shí)現(xiàn)的效果 |
9. | |
10. | @echo off&setlocal enabledelayedexpansion |
11. | (for /f "tokens=1* delims=:" %%a in ('findstr /n .* 1.txt') do ( |
12. | set t2= |
13. | set /p t2= |
14. | echo;%%b!t2! |
15. | ))<2.txt>合并.txt |
16. | ::由于可以有兩個(gè)不同的輸入來源并存,所以雙文本乃至多文本合并就成為輕而易舉的事了 |
無奈的是,可以分段接受重定向輸入的命令寥寥無幾,所以暫時(shí)還沒有想到更多的實(shí)用技巧,還是等待大家來補(bǔ)充吧。
感謝寒夜孤星、mxxcgzxxx、tmplinshi給予指點(diǎn)和共同探討、測(cè)試。
- 1. 批處理(bat)利用set p與重定向輸入分行獲取文本內(nèi)容
- 2. 批處理(bat)學(xué)習(xí)的一些總結(jié)
- 3. ps:利用量尺輕松調(diào)整相片傾斜
- 4. WinSetupFromUSB 制作U盤啟動(dòng)法
- 5. 為了噴mybatis我下載了mybatis源碼
- 6. 利用選擇性粘貼命令完成一些特殊的計(jì)算與Web查詢
- 7. 利用公式來設(shè)置加權(quán)平均及自動(dòng)求和
- 8. 利用圖表工具欄快速設(shè)置圖表,快速選取圖表元素
- 9. 利用WinRAR 功能輕松地備份文件
- 10. Ajax & XMLHttpRequset實(shí)例代碼分享