web-dev-qa-db-ja.com

DOSバッチスクリプトで配列を生成する

DOSのバッチスクリプトで配列変数を設定する方法を教えてください。処理するファイル名のリストをロードしたいのですが。私は本当にこれを可能な限り単純にしたいと思います。ありがとうございました。

33
Jim Fell

私はそれを考え出した:

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%

私は数年前にこのようなことをしました。 (ところで、私はホイールを再発明するのは嫌いです。)これがここに掲載されたので、うまくいけば他の人もそれを役に立つと思います。

48
Jim Fell

はい、配列をバッチで実行できます。 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
12
Patrick Jackson

Jakash3のブログから、 Arrays in Batch はPromptコマンドで配列をエミュレートする方法を説明します。

この記事には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%.

以下の出力を生成します。

image

7
harrymc

これは配列を生成してそれを表示します

名前を書くことによって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! FORやIFの中で変数が正しく振る舞うように、奇妙な振る舞いを防ぐには%var%ではなくが必要です。バッチファイルでは不思議です。詳しくはset /?を参照してください。

これが配列を生成するものであり、配列について知っている人なら誰でも簡単に理解できます。 names[0]=bobnames[1]=tomnames[2]=josephを行うこともできますが、配列の利点の1つは配列にループを追加する機能です。これはここで行ったことです。

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

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

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

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

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

私がFORで難しい方法を学んだこと - あなたはカーソルとしてSINGLE CHARACTER変数を使う必要があります!

1
JNK

これは私がBATCH/CMDで私のチックタックトウゲームからテアレイをテストするためにしばらく行って小さなデバッグファイルです。コード上で大きく複雑になることなく、配列との間で読み書きできます。

使い方は簡単です。

配列への書き込み

  1. ファイルを指定するか、インポートして他のファイルをインポートします。
  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
0
Elforax

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

デフォルトでは、FORはsetまたは単にファイルを処理します。

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

または、再帰的には:

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

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

FOR /D %d DO ECHO %d
0
heavyd

何をしたいのか、それぞれのファイル名に入力変数を使うのはどうでしょうか。%1%2などの変数で選択できます。例えば:mybat.bat file1.nam file2.namなど。

その後、これらの変数をループ内で使用できますが、他の変数を%1の '位置'に移動するためにSHIFTを使用できるので、メインパラメーターとして%1を使用するだけで済みます。 IF "X%1" == "X"のように

例えば:

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

ファイルのリストをfilelist.txtに保存すると、ファイルの各行を読み込んで処理するためのFORが得られます。

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

ファイルの各行を印刷するには(行の最初の "|"まで)。あなた自身の区切り文字を指定しなければ、スペースとタブが使用されます。完全な行を取得するためにファイルに表示されません)。

0
Neal

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

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

私はあなたが探しているのはMakefileであり、そしておそらくあなたに適当なシェルを与えるためのcygwinであると信じています(bash、あるいはあなたのどんな風味でも)。

0
lorenzog

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

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

@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
mordex

バッチファイルでこのようなものは?フォルダ内のファイルを選択してください。 <<コメント、コードなし

: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
tweakradje