2012-02-07 14 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

EDITはなります:私は長い道のりが各1のチェックを行うことであろう知っている..しかし、私はその方法を回避しようとしています:

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

などを

答えて

3

FOR/F "delims = ..."コマンドで項目を直接列挙する方法はありません。それを行うための通常の方法は、1つのアイテムを数えるループを介して、それを文から削除し、カウントされたアイテムがある間繰り返すことです。

ただし、文中の特定の区切り文字および残りの文字に応じて、各項目を標準バッチ区切り記号で区切ってコードを繰り返すFORコマンド(/ Fオプションなし)を使用できます。コンマ、セミコロン、等号、スペースの他に。あなたの特定の例で:

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

カンマ区切りの項目の数を直接数えます。区切り文字はカンマ、セミコロンや等号以外の文字である場合は、可能な解決策は、3段階の方法である:

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

2

代わりにFOR/Fのためのシンプルなを使用するAaciniの提案がない限り、良い解決策です文字列にワイルドカード文字*または?が含まれている可能性があります。 ?文字は検索と置換によって保護されますが、*をバッチで置き換える効率的な方法はありません。

ワイルドカード問題が発生した場合は、ループでFOR/Fを使用して一度に1単語ずつ解析することができます。たいていの人はGOTOを使ってループを完成させます。なぜなら、あなたは何語目を見つけるのかわからないからです。しかし、GOTOは比較的遅いです。任意の数の項目で外部FORループ(FOR/Lではない)を使用することで、パフォーマンスを大幅に向上させることができます。体内では、それ以上の単語がないときは、GOTOでループを終了することができます。ループが消えずに単語を使い果たす場合は、GOTOを使用してループを再開することができます。 100個の項目を持つ外部ループは、100個の解析された単語につき1つのGOTOしか実行しません。 FORループのすべてと同様に

@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/Lは、本体内でGOTOを使用していても、FOR/Lは常にすべての繰り返しのカウントを終了するため、FOR/Lを外部ループに使用しないでください。

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 char( "バグ"ではなく)の特別な処理です。さもなければ、他のデリミタが同じように処理されないのはなぜですか? – Aacini

+0

+1 - 私はこの解決策を忘れていました。それは間違いなく良いものです。 – dbenham

+0

@Aacini - 特別な処理ではありません。 FOR/Fは、入力をどこから取得しているかに関係なく、LFに出会うたびに常に新しい反復を開始します。 – dbenham