DOSバッチスクリプトでの配列の作成


33

DOSバッチスクリプトで配列変数を設定するにはどうすればよいですか?処理するファイル名のリストをロードしたいと思います。これを可能な限りシンプルに保ちたいと思います。ありがとうございました。


1
DOS互換性が本当に必要です、それともPowerShellを使用できますか?
ブライアンノブ

1
これにはvbscriptもかなり簡単に使用できます
JNK

@ブライアン:DOSが必要です。投稿したソリューションをご覧ください。
ジム・フェル

あなたは何の髪を持っていないなら、あなたは確かにpromptコマンドとDOSの違いを知っている必要があります
barlop

回答:


48

私はそれを考え出した:

set FILE_LIST=(file1.dll file2.exe file3.dll file4.dll file5.dll)

set BIN_PATH="C:\Program Files\My App Folder\bin"
set BAK_PATH="C:\Program Files\My App Folder\bin\Backups"
set DEV_PATH="C:\My Dev Path\bin\Debug"

for %%i in %FILE_LIST% do copy %BIN_PATH%\%%i %BAK_PATH%
for %%i in %FILE_LIST% do copy %DEV_PATH%\%%i %BIN_PATH%

数年前に私はこのようなことをしたので、それを理解するのに少し時間がかかりました。(ところで、私は車輪の再発明が嫌いです。)ここに掲載されたので、うまくいけば他の人もそれを役に立つと思うでしょう。


1
まあ、私はあなたがそれを行うことができるとは知りませんでした!私はそれを試してみましたが、うまくいきます!
リンカー3000

これはおそらくDOSでは機能しません。DOSは長いファイル名(8.3のみ)を実行しません。また、私が思い出すように、DOSはファイルパスでも引用符を使用しません。()構文を使用して配列をサポートするかどうかを確認するのに便利なMS-DOSインストールがありません。
CVn

3
これは目的には機能しますが、実際には配列ではないことに注意してください。これは、個々の要素に分割されている単なる文字列です。のようなことをして、要素を直接参照することはできませんFILE_LIST[0]
アフォリア

@MichaelKjörling:FreeDOS はLFNとおそらく引用符をサポートできるので、彼はそれを使用しているのでしょうか?
ネイサンタギー

@NathanTuggy良い点。それでも、その場合は明示的にすればよいでしょう。
CVn

12

はい、配列をバッチで実行できます。CやVBの配列とはまったく異なりますが、次のことができます。

@echo off
setlocal enabledelayedexpansion

set  arrayline[0]=############
set  arrayline[1]=#..........#
set  arrayline[2]=#..........#
set  arrayline[3]=#..........#
set  arrayline[4]=#..........#
set  arrayline[5]=#..........#
set  arrayline[6]=#..........#
set  arrayline[7]=#..........#
set  arrayline[8]=#..........#
set  arrayline[9]=#..........#
set arrayline[10]=#..........#
set arrayline[11]=#..........#
set arrayline[12]=############

::read it using a FOR /L statement
for /l %%n in (0,1,12) do (
echo !arrayline[%%n]!
)
pause

1
素晴らしいとinspringである..私はちょうどその上に構築し、あまりに配列を移入答えやった
barlop

7

Jakash3のブログから、バッチの配列では、コマンドプロンプトで配列をエミュレートする方法について説明しています。

この記事にはarray.batという名前のバッチファイルが含まれており、配列の処理に使用される関数のライブラリが含まれています。記事内のテキストを選択して、batファイル内に貼り付ける必要があります。

たとえば、次のテストスクリプト:

@echo off
set book[0]=Avatar
set book[1]=The Green Mile
set book[2]=The Count of Monte Cristo
call array.bat add book Babo
call array.bat len book length
echo I have %length% books you can borrow.
echo Pick one:
echo.
echo 0) Avatar
echo 1) The Green Mile
echo 2) The Count of Monte Cristo
echo 3) Babo
echo.
set /p pick=
call array.bat getitem book %pick% title
echo.
echo You picked %title%.

次の出力を生成します。

画像


1
私はそれが少し長いです見てもOK、あなたはarray.batの内容がリストされていないのに
barlop

4

これにより、配列にデータが入力されて出力されます

names!i!と書くと、names [1] names [2] names [3]ではなく、names1 names2 names3を使用できます。名前の代わりに[!i!]。変数名を生成して配列を生成します。バッチには配列構造はありません。しかし、それは配列構造と同じようにすてきであり、適切な言語(実際には配列構造を持っています!)

@echo off
setlocal enabledelayedexpansion enableextensions

set i=-1

for %%f in (bob, tom, joseph) do (
 set /a i=!i!+1
 set names[!i!]=%%f
)
set lastindex=!i!

for /L %%f in (0,1,!lastindex!) do ( 
  echo !names[%%f]!
)

出力-

c:\blah>a
bob
tom
joseph

c:\blah>

いくつかの説明

setlocal enabledelayedexpansion enableextensions!のVARと!変な動作を防ぐには、%var%ではなく、変数がFORまたはIF内で適切に動作するようにする必要があります。バッチファイルでは奇妙です。set /?さらに言及されている箇所を参照してください。

これが配列にデータを入力するものであり、配列を知っている人なら誰でも簡単に理解できます。names[0]=bob names[1]=tom names[2]=joseph配列の美しさの1つは、配列をループで埋めることができることでもありますが、これはここで行ったことです。

for %%f in (bob, tom, joseph) do (
 set /a i=!i!+1
 set names[!i!]=%%f
)
set lastindex=!i!

これにより、アレイが表示されます。%% fをエコーすると、1のステップで0から配列の最後のインデックスに移動します。したがって、names [0] names [1] names [2]を出力します。

for /L %%f in (0,1,!lastindex!) do ( 
  echo !names[%%f]!
)

0

何をしたいのか、各ファイル名に入力変数を使用する方法については、%1%2などの変数で取得できます。例:mybat.bat file1.nam file2.namなど。

その後、これらの変数をループで使用できますが、主なパラメーターとして%1を使用するだけで、SHIFTを使用して他の変数を%1 '位置'に移動し、null(変数の終わり)をテストします。 IF "X%1" == "X"など

例えば:

:LOOP
IF "X%1" == "X" GOTO DONE
COPY %1 C:\TARGET.DIR
SHIFT
GOTO LOOP
:DONE

0

ファイルのリストをfilelist.txtに保存するFORと、次のようにファイルの各行を読み取って処理できます。

FOR /F "delims=|" %i  IN (filelist.txt) DO @echo %i

ファイルの各行を印刷するには(行の最初の「|」まで。独自の区切り文字を指定しない場合、スペースとタブが使用されるため、パスにスペースがない場合を除き、文字を指定する必要があります。完全な行を取得するためにファイルに表示されません)。


/ fは実際にはWindows 2000以降の機能です。DOSではありません。
wendy.krieger 14年

0

あなたが言う答えに対するあなたのコメントの一つで、

私は開発作業を行っていますが、毎回アプリケーションの複雑な性質のため、ビルド(多くの場合)をテストしたいため、ビルドバイナリディレクトリからインストールバイナリディレクトリに5つのファイルをコピーする必要があります。これは面倒です。現在、バッチスクリプトにはファイル名がハードコードされていますが、スクリプトを保守しやすくするためにファイル名を配列に入れたいと思います。

あなたが探しているのはMakefileであり、おそらくあなたにまともなシェル(bash、またはあなたの味)を与えるcygwinだと思います。


0

テキスト内の文字列と文字を置き換えます。

テキストをfor本体に展開し、varをvarに置き換えてforループを試行します。setコマンドを呼び出して、%1がユーザー入力になるようにテキストファイルをドラッグアンドドロップします。

@echo off
setlocal EnableDelayedExpansion
set /p a= enter letter to change:
set /p b= letter to change to:
set /p input=<%1
for /f %%c in ("!input:~!") do (
set "code=!input:%a%=%b%!"
echo !code!>myfile.txt
)

0

バッチファイルにこのようなものがありますか?フォルダー内のファイルを選択します。<<はコメント、コードなし

:selectapk
SETLOCAL ENABLEDELAYEDEXPANSION      << DELAYED EXPANSION on for counter in For loop
SET /A MAXITEM=0
Echo.
Echo Found these APK files in "add_apk_here" folder.
Echo.
For %%a in (add_apk_here/*.apk) do (
 Set /A MAXITEM+=1
 Set MENUITEM!MAXITEM!=%%a        << Fill n local env vars, one for each file, called MENUITEM1...n
 Echo    !MAXITEM!. %%a
)
Echo.
If !MAXITEM!==0 Echo No APK in "add_apk_here" folder & call :delay & Goto start   << No apk files then go back
SET /P CHOICE=Select APK to work on: 
SET MENUITEM=!MENUITEM%CHOICE%!      << Get the stored filename from MENUITEMx
SETLOCAL DISABLEDELAYEDEXPANSION     << Very important for next ENDLOCAL that doesn't like the delayedexpansion var
ENDLOCAL & SET apk=%MENUITEM%        << put the local MENUITEM var into the global apk var
goto start

:delay
REM %1 like Call :delay 5
SETLOCAL
SET N=%1
If Not Defined N Set N=2
Ping -n %N% -w 1000 127.255.255.255 > nul
ENDLOCAL
Exit /b

0

本当にできないコマンドプロンプトで配列を実行する(また、Windows 3.1を実行していない限り、実際にはDOSでもありません)。ただし、FORコマンドを使用してセットベースの処理を実行できます

処理するファイルのリストを作成するには、処理するテキストファイルを手動で作成するか、 dir /b <mask>、FORループ内でコマンドをます。

FORで苦労して学んだこと- カーソルとしてSINGLE CHARACTER変数を使用する必要があります!


+1は、下票を説明する必要があるとコメントします。また、「カーソルとしてSINGLE CHARACTER変数を使用する必要があります!」<-カーソルとしてではなくインデックスとして
14

1
また、Win9XブートディスクがDOS(DOS 7)である場合にも注意してください。そして、Windows 9Xは依然としてDOS上で動作すると言われていました。行を追加して、bootscan = 0やbootgui = 0のようなmsdos.sysで、Windowsでの起動を停止し、DOSプロンプトで直接起動すると思います。
barlop 14

0

FORバッチコマンドに関するMicrosoftのドキュメントを参照してください。FORを使用して、一連のディレクトリ、ディレクトリ内のファイル、またはディレクトリとそのすべてのサブディレクトリ内のファイルを反復処理できます。

デフォルトでは、FORはセットまたはファイルのみを処理します。

FOR %f IN (*.txt) DO ECHO %f

または、再帰的に:

FOR /R %f IN (*.txt) DO ECHO %f

または、ディレクトリだけの場合:

FOR /D %d DO ECHO %d

残念ながら、これらのオプションはすべて、それぞれの範囲にすべて含まれています。私は開発作業を行っていますが、毎回アプリケーションの複雑な性質のため、ビルド(多くの場合)をテストしたいため、ビルドバイナリディレクトリからインストールバイナリディレクトリに5つのファイルをコピーする必要があります。これは面倒です。現在、バッチスクリプトにはファイル名がハードコードされていますが、スクリプトを保守しやすくするためにファイル名を配列に入れたいと思います。
ジム・フェル

0

これは、BATCH / CMDでのtic tac towゲームのte配列をテストするためにしばらく作成した小さなデバッグファイルです。コード上で大きく複雑になることなく、配列の読み取りと書き込みを行うことができます。

使い方は簡単です:

配列への書き込み

  1. それにファイルを与えるか、それを変更して他のsomtingをインポートします。
  2. 配列に名前を付けます。
  3. 完了しました。

配列からの読み取り

  1. 読み取りたい配列またはその一部のサイズを指定します。
  2. 名前に%% aを含む配列の名前を入力します
  3. 完了しました。

コード:

@echo off
setlocal EnableDelayedExpansion

set ID=0

::              Reader                   ::
:: It reads the file called input.txt    ::
:: and stores it in a new variable that  ::
:: for everytime it goes over it it is a ::
:: new ID (Slot in the array).           ::

For /F %%A in (input.txt) do ( 
    set /a ID=ID+1
    set Input!ID!= %%A

    echo !ID! : %%A
)


::             Writer                     ::
:: this is to read all Slots in the array ::
:: and puts it on the screen.             ::

for /L %%a in (1,1,!ID!) do (
    echo !Input%%a!
)
pause>nul
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.