2

以下のバッチスクリプトがあります。テキスト ファイルの各行の最初の文字を読み取る必要があります。それはa to 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! )

)
4

4 に答える 4

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 コマンドを使用しないため、高速です。

編集いくつかの説明が追加されました

以下の次の例では、最初にコマンドを書き、次にその出力を書きます。

letters変数には 26 文字が含まれます。つまり、次のとおりです。

echo !letters!
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Batch では、変数値の一部を次のように置き換えることができます。

echo !letters:M=123!
ABCDEFGHIJKL123NOPQRSTUVWXYZ

置換文字列が指定されていない場合、元の部分文字列が削除されます。

echo !letters:M=!
ABCDEFGHIJKLNOPQRSTUVWXYZ

元の部分文字列が別の variableに含まれている場合、置換はその値で実現されます。たとえば、変数に文字がある場合:

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

一方、変数に文字がない場合、新しい値は元の値と同じままです。

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

このように、 と比較する"!letters:%str%=!""%letters%"; 結果が DIFFERENT の場合、str 変数には文字が含まれます。それ以外の場合、str 変数にはアルファベット以外の文字が含まれています。

ただし、 FOR ループで str 変数が変更されることに注意する必要があります。これは、DelayedExpansion を使用してその値を置き換える必要があることを意味しますが、これは次のようなおかしなコードに"!letters:!str!=!"なります。もちろん、これは無効です。この詳細を修正する方法は!str!、FOR 置換可能パラメーターによって値を変更し、そのパラメーターを部分文字列置換式で使用することです。

以前の置換は、バッチ ファイルの通常の処理として、すぐに cmd.exe プロセッサによって行われることに注意してください。一方、 の実行では、パイプラインの両側を実行するためにECHO !str! | FINDSTR /I "[A-Z]"、FINDSTR.EXE ファイル (約 30 KB サイズ) のロードとCMD.EXE の2 つのコピーの実行が必要であり、このプロセスは名前ごとに実行されます。リストに!. これは、この方法が前の方法よりもはるかに遅いことを意味し、名前のリストが大きい場合、タイミングの違いは明らかです。

于 2013-04-13T00:19:40.380 に答える
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 Wright に感謝します。)

于 2013-04-12T19:39:16.930 に答える
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!"
)

このアプローチとの違いの 1 つは、分音記号を含む英語以外の文字も文字としてカウントされることです。これらの英語以外の文字はすべて、127 より大きい拡張 ASCII コードを持っています。これは、Andriy の FINDSTR メソッドが取得した結果と同じです。

于 2013-04-13T11:48:19.857 に答える