Windowsバッチファイルを使用して、テキストファイルの各行をどのようにループしますか?


244

Windowsバッチファイルを使用してテキストファイルの各行をループ処理し、テキストの各行を連続して処理する方法を知りたいです。

回答:


304

以下の投稿は大いに役立ちましたが、行全体を処理する必要がある場所で私の質問に述べたとおりにはいきませんでした。これが私が機能することがわかったものです。

for /F "tokens=*" %%A in (myfile.txt) do [process] %%A

アスタリスク(*)を含むtokensキーワードは、行全体のすべてのテキストを引き出します。アスタリスクを入力しない場合は、行の最初の単語のみが取得されます。スペースに関係していると思います。

TechNetのCommand

すべての投稿に感謝します!


ファイルパスにスペースがある場合は、を使用する必要がありますusebackq。例えば。

for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A

37
マイナーの追加:、対話的にコマンドラインからこの作業を行う交換する%%A%A上記のコマンドインチ そうでなければあなたは得るでしょう%%A was unexpected at this time.
vadipp

16
参考までに、複数行のコマンドを実行する必要がある場合は、「DO」の後に開き括弧「(」を置き、数行後に閉じ括弧「)」で終わらせることができます。コードを置くだけで済みます。それらの内部をブロックします(好みに応じてインデントします)。
BrainSlugs83 2013年

3
そのパターンをありがとう。私は、ファイル名の前後に引用符( ")に置くことができないことを発見した- 。ちょうど私にファイル名を与え、スペースを含むファイル名の場合を例:for /F "tokens=*" %%A in ("myfile.txt") do echo A = %%A- > A = myfile.txtこれを阻止するためにどのように任意のアイデア?
意志

1
作業しているファイルがANSIまたはUTF8でエンコードされていることを確認してください。TYPEコマンドを使用してファイルを表示しようとして、出力が期待したものにならないまで、これが機能しない理由について頭を悩ませていました。この時点で、なんらかの理由でファイルが「UCS-2 BE BOM」でエンコードされていることに気付きました。
Dan Stevens

1
ループのインデックスパラメータは単一の文字でなければならないことを指摘しておく価値があります。たとえば、%% iは問題ありませんが、%% indexは失敗します。
ヴィンセント

59

Windowsコマンドラインリファレンスから:

コメント行を無視してファイルを解析するには、次のように入力します。

for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do @echo %i %j %k

このコマンドは、Myfile.txtの各行を解析し、セミコロンで始まる行を無視し、2番目と3番目のトークンを各行からFOR本文に渡します(トークンはコンマまたはスペースで区切られます)。FORステートメントの本体は、%iを参照して2番目のトークンを取得し、%jを参照して3番目のトークンを取得し、%kを参照して残りのすべてのトークンを取得します。

指定するファイル名にスペースが含まれている場合は、テキストを引用符で囲みます(たとえば、「ファイル名」)。引用符を使用するには、usebackqを使用する必要があります。それ以外の場合、引用符は解析するリテラル文字列を定義するものとして解釈されます。

ちなみに、ほとんどのWindowsシステムのコマンドラインヘルプファイルは次の場所にあります。

 "C:\WINDOWS\Help\ntcmds.chm"

8
するために明確に「引用符を使用するには、使用しなければなりませんusebackqfor /f "usebackq" %%a in ("Z:\My Path Contains Spaces\xyz\abc.txt")
drzaus

35

バッチファイルでは、しなければならない使用%%の代わりに%:(タイプhelp for

for /F "tokens=1,2,3" %%i in (myfile.txt) do call :process %%i %%j %%k
goto thenextstep
:process
set VAR1=%1
set VAR2=%2
set VAR3=%3
COMMANDS TO PROCESS INFORMATION
goto :EOF

これが何をするか:forコマンドの最後にある "do call:process %% i %% j %% k"は、myfile.txtからforコマンドで取得した情報を "process" 'subroutine'に渡します。

バッチプログラムでforコマンドを使用している場合は、変数に二重の%記号を使用する必要があります。

次の行は、これらの変数をforコマンドからプロセスの「サブルーチン」に渡し、この情報を処理できるようにします。

set VAR1=%1
 set VAR2=%2
 set VAR3=%3

この正確な設定のかなり高度な使用法がいくつかあります。さらに例が必要な場合は、喜んで共有します。もちろん、必要に応じてEOLまたはDelimsを追加します。


27

最初の "FOR / F .."の回答の改善:私がしなければならなかったことは、MyList.txtにリストされているすべてのスクリプトを実行するように呼び出すことでした。

for /F "tokens=*" %A in  (MyList.txt) do CALL %A ARG1

-または、複数行にわたって実行する場合:

for /F "tokens=*" %A in  (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)

編集:上記の例は、コマンドプロンプトからFORループを実行するためのものです。バッチスクリプトから、以下に示すように、追加の%を追加する必要があります。

---START of MyScript.bat---
@echo off
for /F "tokens=*" %%A in  ( MyList.TXT) do  (
   ECHO Processing %%A.... 
   CALL %%A ARG1 
)
@echo on
;---END of MyScript.bat---

21

@MrKrausの答えは有益です。さらに、バッチファイルと同じディレクトリにあるファイルをロードする場合は、ファイル名の前に%〜dp0を付けます。次に例を示します。

cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A

注:ファイル名またはディレクトリ(上記の例のmyfile.txtなど)にスペース(たとえば、 'my file.txt'または 'c:\ Program Files')がある場合は、次を使用します。

for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A

typeキーワードを使用してtypeプログラムを呼び出し、テキストファイルの内容を表示します。typeコマンドを呼び出すことによるオーバーヘッドを望まない場合は、ディレクトリをテキストファイルのディレクトリに変更する必要があります。スペースを含むファイル名の場合もtypeが必要であることに注意してください。

これが誰かを助けることを願っています!


バッチファイルはデフォルトで現在のフォルダーを検索するため、ファイル名にプレフィックスを付ける必要はありません。
foxidrive 2013年

1
@foxidrive:わかりました。注意が必要ですが。たとえば、ディレクトリが変更された場合、バッチファイルがあるディレクトリではなく、そのディレクトリが検索されます。解決策は**cd /d %~dp0**、forループの前に呼び出されます。これにより、バッチファイルが置かれているディレクトリ内のファイルを参照していることを確認できます。観察をありがとう
Marvin Thobejane

2
以下のためのTHXと1 typewalkaround
ハレックス

typeスペースが含まれている別のディレクトリにあるため、ファイル名を引用符で囲まなければなりませんでした(くそーProgram Files)。エラーが発生するThe system cannot find the file `type.
scragar

1
@scragar、あなたは正しい見積もりを持っていますか?'ではなく'である必要があります。私のキーボードでは、@と同じキーにあります
FrinkTheBrave 14

18

受け入れられた答えは良いですが、2つの制限があります。
空の行と次で始まる行をドロップします;

コンテンツの行を読み取るには、拡張の切り替えを遅らせるテクニックが必要です。

@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ text.txt"`) do (
    set "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    echo(!var!
    ENDLOCAL
)

Findstrは、各行の先頭に行番号とコロンを付けるために使用されるため、空の行はもはや空ではありません。

%%aパラメータにアクセスするとき、DelayedExpansionを無効にする必要があります。無効にすると、感嘆符!とキャレット^はそのモードで特別な意味を持つため失われます。

ただし、行から行番号を削除するには、遅延拡張を有効にする必要があります。
set "var=!var:*:=!"最初のコロンまでをすべて削除します(delims=:findstrからのものだけでなく、行の先頭にあるすべてのコロンも削除します)。
endlocalは、次の行の遅延拡張を再び無効にします。

唯一の制限は行の長さの制限である〜8191ですが、これを克服する方法はないようです。


勝利10はsetlocalコマンドラインで許可していません。CMDでコードを実行すると、!var!ブランクの代わりに。直し方?
ジンバ

行の長さの制限は、処理前にファイルを最大行長8190の一時ファイルに分割することで克服できます。次に、1つのファイルに再結合します。
ジンバ

14

または、引用符でオプションを除外することもできます。

FOR /F %%i IN (myfile.txt) DO ECHO %%i

1
隣接する2つのパーセント記号%%は、コマンド(バッチファイルではない)では単一のパーセント記号のように扱われます。
ポール、

9

これは、フォルダー内のすべてのSQLスクリプトを実行するために私が書いたbatファイルです。

REM ******************************************************************
REM Runs all *.sql scripts sorted by filename in the current folder.
REM To use integrated auth change -U <user> -P <password> to -E
REM ******************************************************************

dir /B /O:n *.sql > RunSqlScripts.tmp
for /F %%A in (RunSqlScripts.tmp) do osql -S (local) -d DEFAULT_DATABASE_NAME -U USERNAME_GOES_HERE -P PASSWORD_GOES_HERE -i %%A
del RunSqlScripts.tmp


6

cmd.exeとを使用して承認されたanwser

for /F "tokens=*" %F in (file.txt) do whatever "%F" ...

「通常の」ファイルに対してのみ機能します。それは巨大なファイルで惨めに失敗します。

大きなファイルの場合、Powershellと次のようなものを使用する必要がある場合があります。

[IO.File]::ReadLines("file.txt") | ForEach-Object { whatever "$_" }

または、十分なメモリがある場合:

foreach($line in [System.IO.File]::ReadLines("file.txt")) { whatever "$line" } 

これは、200万行を超える250 MBのファイルで機能for /F ...し、数千行後にコマンドがスタックしました。

間の違いのためにforeachForEach-Object、参照ノウのForEachとのForEach-Objectにへの行き方

(クレジット:PowerShellで1行ずつファイルを読み取る


1

Heroku上のRailsアプリをリストするためにここで変更された例-ありがとう!

cmd /C "heroku list > heroku_apps.txt"
find /v "=" heroku_apps.txt | find /v ".TXT" | findstr /r /v /c:"^$" > heroku_apps_list.txt
for /F "tokens=1" %%i in (heroku_apps_list.txt) do heroku run bundle show rails --app %%i

完全なコードはこちら


上記の別の質問に対するコメントごと-ファイルの作成/読み取りをスキップして使用することができますfor /f "tokens=1" %%i in ('find /v "=" heroku_apps.txt ^| find /v ".TXT" ^| findstr /r /v /c:"^$"') do...^パイプをエスケープするために使用されるの追加に注意してください。これによりfor、コマンドプロセッサにではなく直接渡されます)
user66001

0

コマンドラインからテキストファイルのすべての行を出力するには(delayedExpansionを使用):

set input="path/to/file.txt"

for /f "tokens=* delims=[" %i in ('type "%input%" ^| find /v /n ""') do (
set a=%i
set a=!a:*]=]!
echo:!a:~1!)

先頭の空白、空白行、空白行で動作します。

Win 10 CMDでテスト済み


神試みが、先頭あなたの最初のサンプル削除し]]]ラインから、第二のサンプルは、スペースで始まる空行と行をドロップ
ジェブ

2つ目は空白行を削除するためのものです。1つ目はdelims、テキストファイルのいずれかの行が、]たとえば、ない文字、またはバックスペースやベルなどの制御文字に置き換えます。それらは通常テキストファイルにはありません。その理由delims=]は、/nof findコマンドで作成されたプレースホルダーを削除して空白行を保持するためです。
ジンバ

@jeb:ブラケット]]]の問題が修正されました。テキストファイルのすべての行を印刷するには、更新を参照してください。Win 10 CMDでも動作します。
ジンバ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.