2013-04-12 70 views
2

我有下面的批處理腳本。它應該讀取文本文件每行的第一個字符。這是一個z,它應該在相應的文件夾中創建一個子文件夾。這是別的,它應該在「_other」文件夾中創建。使用索引字母從文本文件創建文件夾

所以,如果我有一個列表:

123test 
aaatest 
bbbtest 

應該創建:

c:\dirs\_other\123test 
c:\dirs\a\aaatest 
c:\dirs\b\bbbtest 

但由於某些原因我最後的if/else不起作用。爲什麼不?這是腳本:

setlocal EnableDelayedExpansion 
set file=c:\klantenlijst.txt 
FOR /F "delims=~" %%i IN (!file!) DO (
set var=%%i 
set str=!var:~0,1! 
IF !str!==A (set letter=1) 
IF !str!==B (set letter=1) 
IF !str!==C (set letter=1) 
IF !str!==D (set letter=1) 
IF !str!==E (set letter=1) 
IF !str!==F (set letter=1) 
IF !str!==G (set letter=1) 
IF !str!==H (set letter=1) 
IF !str!==I (set letter=1) 
IF !str!==J (set letter=1) 
IF !str!==K (set letter=1) 
IF !str!==L (set letter=1) 
IF !str!==M (set letter=1) 
IF !str!==N (set letter=1) 
IF !str!==O (set letter=1) 
IF !str!==P (set letter=1) 
IF !str!==Q (set letter=1) 
IF !str!==R (set letter=1) 
IF !str!==S (set letter=1) 
IF !str!==T (set letter=1) 
IF !str!==U (set letter=1) 
IF !str!==V (set letter=1) 
IF !str!==W (set letter=1) 
IF !str!==X (set letter=1) 
IF !str!==Y (set letter=1) 
IF !str!==Z (set letter=1) 

IF !letter!==1 (md c:\Dirs\!str!\!var!) ELSE (md c:\Dirs\_Other\!var!) 

) 
+0

發佈文件klantenlijst.txt – Endoro

+0

它包含僅用於測試4條記錄。全部0-9,a-z,A-Z和空格 – Mbrouwer88

回答

2

這是驗證字符是否是字母的另一種快速方法。

@echo off 
setlocal EnableDelayedExpansion 
set file=c:\klantenlijst.txt 
for /f "delims=" %%i IN (%file%) do (
    set var=%%i 
    set str=!var:~0,1! 
    if /i "!str!" geq "A" if /i "!str!" leq "Z" set "str=_other" 
    md "c:\dirs\!str!\!var!" 
) 

這種方法的一個區別是帶有變音符號的非英文字母也會被計爲字母。這些非英文字母都具有大於127的擴展ASCII碼。這與Andriy的FINDSTR方法得到的結果相同。

+0

當你說「上述方法」時,你的意思是@ Aacini的,對吧?因爲我看不到你的建議的結果會與我的不同。 –

+0

@AndriyM - 通過以上,我的意思是我的答案 - 一個糟糕的詞選擇。我相信我們的方法會給出相同的結果,是的。 – dbenham

+0

啊,我明白了,儘管我自己經常用「上面」一詞來指代我自己帖子中的部分文字,但我相信我的看法有些歪曲。對我來說是一個雙重教訓。也許你不需要因爲我而改變措辭,但是非常感謝你跳到它! –

1

這並不適用於a工作,只爲A

IF !str!==A (set letter=1) 

將其替換爲:

IF /i !str!==A (set letter=1) 
+0

感謝您的幫助!我加了/我忽略了這些字母的大小寫,並刪除了空格,使得letter = 1。最後一個問題是腳本中的行包含空格,這會導致問題。如何解決這個問題?我需要添加引號嗎? – Mbrouwer88

+0

最好的是:'IF/i「!str!」==「A」set/a letter = 1' – Endoro

3

您可以使用FINDSTR以測試第一個字符是字母:

... 
ECHO !str! | FINDSTR /I "[A-Z]" 1>NUL && (
    command to execute if !str! is a letter 
) || (
    command to execute if !str! is not a letter 
) 
... 

"[A-Z]"模式匹配任何字母,而/I開關使匹配不區分大小寫。

例如,如果不是字母,則可以將str設置爲_other。這樣,使用值作爲其子文件夾應該創建的文件夾的名字時,你就不需要任何更多的條件:

... 
ECHO !str! | FINDSTR /I "[A-Z]" 1>NUL || (
    SET str=_other 
) 
MD "c:\Dirs\!str!\!var!" 
... 

也請注意路徑周圍的雙引號MD。當路徑包含空格或其他特殊字符時,這是必需的。 (感謝@Peter賴特注)

+2

哦,非常好!儘管如此,在原始代碼中,Endoro還指出了另外兩個超出「/ i」要求的錯誤。第一個是'letter'被賦值爲''1''而不是''1'',因爲該空間被包含在一個字符串'set'中。你可以通過消除'1'後面的空格或者使用'set/a'來解決這個問題。第二個是,一旦設置了「字母」,它就永遠不會是UNset,所以在第一個LETTER字符後面出現的任何非字母首字符也將被歸類爲一個字母...... – Magoo

+0

感謝所有幫助!我加了/我忽略了這些字母的大小寫,並刪除了空格,使得letter = 1。最後一個問題是腳本中的行包含空格,這會導致問題。如何解決這個問題?我需要添加引號嗎? – Mbrouwer88

+2

引用要創建的目錄名,就像這樣「IF!letter!== 1(md」c:\ Dirs \!str!\!var!「)ELSE(md」c:\ Dirs \ _Other \!var!「) 「如果我正確地理解了它,應該治好你的空間問題。 – Magoo

5

這是我會做的方式:

@echo off 
setlocal EnableDelayedExpansion 
set letters=ABCDEFGHIJKLMNOPQRSTUVWXYZ 
set file=c:\klantenlijst.txt 
FOR /F "delims=" %%i IN (%file%) DO (
    set var=%%i 
    set str=!var:~0,1! 
    for %%a in ("!str!") do if "!letters:%%~a=!" equ "%letters%" set str=_other 
    md "c:\dirs\!str!\!var!" 
) 

上述程序試圖刪除包含所有字母的字符串的第一個字符;如果結果相同,則第一個字符不是字母。此方法更快,因爲它不使用任何外部.exe命令。

EDIT幾點說明加入

在接下來的實施例下面我寫第一命令,然後其輸出。

letters變量包含26個字母,那就是:

echo !letters! 
ABCDEFGHIJKLMNOPQRSTUVWXYZ 

批允許替換變量值的一部分是這樣的:如果替換字符串沒有給出

echo !letters:M=123! 
ABCDEFGHIJKL123NOPQRSTUVWXYZ 

中,原始子字符串剛被刪除:

echo !letters:M=! 
ABCDEFGHIJKLNOPQRSTUVWXYZ 

如果原點al子字符串包含在另一個變量中,替換是通過它的值來實現的。例如,如果變量有一個字母:

set str=M 
echo !letters:%str%=! 
ABCDEFGHIJKLNOPQRSTUVWXYZ 

在另一方面,如果變量沒有一個字母,新的值保持和原來一樣:

set str=1 
echo !letters:%str%=! 
ABCDEFGHIJKLMNOPQRSTUVWXYZ 

這樣,如果您比較"!letters:%str%=!""%letters%";如果結果是不同的,那麼str變量包含一個字母;否則str變量包含一個非字母字符。

但是,您必須注意str變量在之內被修改爲FOR循環。這意味着它的值必須使用DelayedExpansion來替換,但是這會導致以下有趣的代碼:"!letters:!str!=!"當然這是無效的。修正這個細節的方法是通過FOR可替換參數改變!str!值,然後在替換子字符串表達式中使用該參數。

您必須注意,以前的替換是由cmd.exe處理器立即作爲批處理文件的正常處理來實現的。另一方面,執行ECHO !str! | FINDSTR /I "[A-Z]"需要加載FINDSTR.EXE文件(約30 KB大小)和執行兩個副本的CMD.EXE以便執行管道的每一側,並且執行該過程爲列表中的每個名字!。這意味着這種方法比前者慢,並且如果名稱列表很大,時間差異將是明顯的。

+0

您的意思是'上面的腳本嘗試'嗎?我對理解它有點困難:) – user2033427

+0

@ user2033427:我在我的答案中加入了一些解釋... – Aacini

+0

+1,但是MD路徑應該在空格的情況下引用。 – dbenham