1. ホーム
  2. スクリプト・コラム
  3. DOS/BAT(ドス・バット

バッチ処理における文字列分割コード

2022-01-01 17:25:41

文字列の一括分割の例

文字列はforコマンドで分割することができます。

文字列を分割する

@echo off
::Define a semicolon delimited string
set str=AAA;BBB;CCC;DDD;EEE;FFF
::A copy of str
set remain=%str%
:loop
for /f "tokens=1* delims=;" %%a in ("%remain%") do (
	::Output the first segment (token)
	echo %%a
	rem assign the rest of the intercept to the variable remain, you can actually use the delayed variable switch here
	set remain=%%b
)
::If there is still left, continue the segmentation
if defined remain goto :loop
pause


主にfor文の説明です。

delims=; は、残った文字列をセミコロンをセパレータとして分割することを意味します。
tokens=1*, tokensは分割の仕方、tokens=1*は最初の区切り、前の区切りは部分、残り(*は部分)を意味しています。この2つの部分は、ループ本体では常に、最初の部分は%%a、2番目の部分は%%bで表すことができます。

バッチ処理 パス環境変数に対する反復処理

バッチではパス環境変数もセミコロンで区切られていることが分かっているので、上記のコードでパス環境変数を反復処理することも可能です。

@echo off
setlocal enabledelayedexpansion 
::Define a semicolon-delimited string
set str=%path%
::A copy of str
set remain=%str%
:loop
for /f "tokens=1* delims=;" %%a in ("%remain%") do (
	::Output the first segment (token)
	echo %%a
	rem assign the rest of the intercept to the variable remain, you can actually use the delayed variable switch here
	set remain=%%b
)
::If there is still left, continue the segmentation
if defined remain goto :loop
pause


結果を実行します。

D:\workspace@MarkdownTools
......
C:³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³
D:\dev\java\jdk1.8.0_91\bin
F:\Program Filesnodejs
F:\Program Files/Gitbin
D:\dev ゙apache-maven-3.5.4bin
......
続行するには、いずれかのキーを押してください。. .

環境変数pathにディレクトリが存在するかどうかを判断するバッチ処理

例えば、システムのパス環境変数に D:\dev

MarkdownTools というディレクトリが存在するかどうかを調べます。

@echo off
setlocal enabledelayedexpansion 
::define a semicolon delimited string
::set str=AAA;BBB;CCC;DDD;EEE;FFF
set str=%path%
::copy of str
set remain=%str%
set toFind=D:\dev\workspace\MarkdownTools
set isFind=false
:loop
for /f "tokens=1* delims=;" %%a in ("%remain%") do (
	if "%toFind%"=="%%a" (
		:: set the flag for subsequent use
		set isFind=true
		::stop finding if found
		goto :found
	)
	rem assign the rest of the intercept to the variable remain, you can actually use the delayed variable switch here
	set remain=%%b
)
::If there is still something left, continue to split
if defined remain goto :loop
:found
echo %isFind%
pause


結果を実行します。

続行するには、いずれかのキーを押してください。. .

参考文献

最近、シェルスクリプトの機能をwindowsに移行するという小さな要件があったのですが、シェルには配列の概念があるのにwindowsにはないこと、シェルで文字列分割を扱う方法はいろいろありますが、バットではチキンなようで、いろいろ検索して、ようやく解決しました(Stack Overflow: http://) stackoverflow.com/questions/1707058/how-to-split-a-string-in-a-windows-batch-file).

解決方法 forループによる処理で、通常のforとforファイル処理の2つの方法があります。

オプション1

@echo off & setlocal
rem Note the definition of s here, the value is not caused by the use of double quotes
rem also works for comma-separated lists, e.g. ABC,DEF,GHI,JKL
set s=AAA BBB CCC DDD EEE FFF
for %%a in (%s%) do echo %%a

オプション 2: は、(ほとんどの) 任意の区切り文字に最適です。

@echo off & setlocal
set s=AAA BBB CCC DDD EEE FFF
set t=%s%
:loop
for /f "tokens=1*" %%a in ("%t%") do (
 echo %%a
 rem assign the rest of the intercept to t. You can actually use a delayed variable switch here
 set t=%%b
 )
if defined t goto :loop

ある男が、より完全なもの (遅延変数を使用) を提供しました。

@echo off
setlocal ENABLEDELAYEDEXPANSION

REM Set a string with an arbitrary number of substrings separated by semi colons
set teststring=The;rain;in;spain

REM Do something with each substring
:stringLOOP
 REM Stop when the string is empty
 if "!teststring!" EQU "" goto END

 for /f "delims=;" %%a in ("!teststring!") do set substring=%%a

  REM Do something with the substring - 
  REM we just echo it for the purposes of demo
  echo !substring!

REM Now strip off the leading substring
:striploop
 set stripchar=!teststring:~0,1!
 set teststring=!teststring:~1!

 if "!teststring!" EQU "" goto stringloop

 if "!stripchar!" NEQ ";" goto striploop

 goto stringloop
)

:END
endlocal

そして、これ。

set input=AAA BBB CCC DDD EEE FFF
set nth=4
for /F "tokens=%nth% delims= " %%a in ("%input%") do set nthstring=%%a
echo %nthstring%

Powershellには、実際にはもっと多くの組み込み関数があるはずです。

<ブロッククオート

PS C:\"AAA BBB CCC DDD EEE FFF".Split()

また、batをvbscrip:に置き換えることも提案されています。

Set objFS = CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
str1 = objArgs(0)
s=Split(str1," ")
For i=LBound(s) To UBound(s)
 WScript.Echo s(i)
 WScript.Echo s(9) ' get the 10th element
Next
usage:
c:\test> cscript /nologo test.vbs "AAA BBB CCC"

最後に、batのちょっとした難点:変数の遅延(トップダウン、行単位(単純文、複合文(for、ifブロックは1つとして数える))実行、行単位ではない)。

変数遅延の説明 call setlocal

以上、バッチ処理における文字列分割コードの詳細でしたが、バッチ処理における文字列分割の詳細については、スクリプトハウスの他の関連記事にもご注目ください!