2012-02-07 57 views
1

我有一個FOR/F語句,我希望它枚舉命令解析的分隔符。例如:枚舉FOR/F語句的分號

FOR /F "delims=," %%A IN ("This,is,a,comma,delimited,sentence") DO (
    some command to enumerate delims 
) 
:OUT 

我希望它能說明該句子中每個分隔的項目。在這種情況下,將輸出6

編輯:我知道了很長的路是做在每一個檢查..但我試圖避免方法:

IF %%A == [] SET enum=0 && GOTO:OUT 
IF %%B == [] SET enum=1 && GOTO:OUT 

回答

3

沒有辦法直接枚舉FOR/F「delims = ...」命令中的項目。通常的做法是通過一個循環來計算一個項目,將其從句子中刪除,並在計數項目時重複。

但是,根據句子中特定的分隔符和字符的其他部分,可以使用FOR命令(不帶/ F選項),該命令將REPEAT代碼與由標準批量分隔符分隔的每個項目逗號,分號和等號,除了空格。在您的具體示例中:

SET ENUM=0 
FOR %%A IN (This,is,a,comma,delimited,sentence) DO SET /A ENUM+=1 

直接計算逗號分隔項目的數量。如果分隔符是不是逗號,分號或等號以外的字符,一個可能的解決方案是一個三步法:

1- Replace spaces, comma, semicolon and equal-sign for another know character(s). 
2- Replace the delimiter for any Batch standard delimiter (space, comma, etc). 
3- Use a simple FOR to directly enumerate the items. 
+0

有趣的是,我從來不知道FOR可以做這樣的事情。我一直認爲標準的FOR循環僅用於迭代文件。最重要的是,它知道停止閱讀逗號,分號和等號? – Mechaflash 2012-02-08 14:17:35

2

Aacini的建議,用一個簡單的用於代替FOR/F是一個很好的解決方案,除非該字符串可能包含通配符*??字符可以通過搜索和替換來保護,但是沒有有效的方法可以批量替換*

如果遇到通配符問題,則可以在一個循環中恢復使用FOR/F來一次解析一個單詞。大多數人使用GOTO來完成循環,因爲你無法知道你會找到多少單詞。但GOTO相對較慢。通過對任意數量的項目使用外部FOR循環(而非FOR/L),可以顯着提高性能。只要沒有其他單詞,就可以在主體內用GOTO退出循環。如果循環沒有耗盡單詞,可以使用GOTO重新啓動循環。 100個項目的外部循環將僅每100個分析的詞語執行1個GOTO。

@echo off 
setlocal enableDelayedExpansion 
set "str=This,is,a,comma,delimited,sentence" 
set "L10=1 2 3 4 5 6 7 8 9 0" 
:loop - The outer FOR loop can handle 100 words before a single GOTO is needed 
for %%. in (%L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10%) do (
    for /f "tokens=1* delims=," %%A in ("!str!") do (
    echo %%A 
    if "%%B" == "" goto :break 
    set "str=%%B" 
) 
) 
goto :loop 
:break 

與所有FOR循環,你如果當%%變量擴展啓用延遲擴展必須擔心的!^腐敗。

FOR/L不應該用於外部循環,因爲FOR/L總是完成所有迭代的計數,即使您在體內使用GOTO也是如此。

3

有一種方法可以直接枚舉FOR/F「delims = ...」命令中的項目。
你只需要在字符串中插入一些換行符。

setlocal EnableDelayedExpansion 
set LF=^ 


rem ** Two empty lines are required 

set count=0 
FOR /F "tokens=* delims=" %%a in ("item1!LF!item2!LF!item3") DO (
    set /a count+=1 
    echo !count!: "%%a" 
) 
echo(
set "CSV=This,is,a,comma,delimited,sentence" 
echo Or with comma separeted text: !CSV! 
for %%L in ("!LF!") do set "CSV=!CSV:,=%%~L!" 
set count=0 
FOR /F "tokens=* delims=" %%a in ("!CSV!") DO (
    set /a count+=1 
    echo !count!: "%%a" 
) 
+0

哇,太棒了!但是,我仍然不明白爲什麼這種方法有效。我一直認爲'FOR/F %% x IN(「string」)'不是一個_repetitive_命令,而是一種特殊形式的FOR,它將一個字符串分隔爲標記並執行命令ONCE。你的例子顯示,用「delims =」和插入在字符串中的LF(「tokens =」是不必要的),FOR/F再次以一個重複的命令轉換!這是一個特殊的LF字符處理(不是「bug」);否則,爲什麼其他分隔符不以相同的方式處理? – Aacini 2012-02-09 03:39:59

+0

+1 - 我忘了這個解決方案。這是一個很好的例子。 – dbenham 2012-02-09 18:22:12

+0

@Aacini - 它不是特殊處理。無論遇到LF,FOR/F都會始終開始一個新的迭代,無論它從哪裏獲取輸入。 – dbenham 2012-02-09 18:26:21