web-dev-qa-db-ja.com

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

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

218
Mr. Kraus

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

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

アスタリスク(*)の付いたtokensキーワードは、行全体のすべてのテキストを取得します。アスタリスクを付けないと、行の最初の単語だけが表示されます。スペースと関係があると思います。

TechNetのコマンド

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


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

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

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

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

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

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

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

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

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

バッチファイルでは、%%の代わりに%を使用する必要があります。(Type 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"サブルーチンに渡します。

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

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

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

私はこの正確なセットアップのかなり高度な使用法をいくつか持っています。それ以上の例が必要ならば私は喜んでそれを共有するでしょう。もちろん、必要に応じてEOLまたはDelimを追加してください。

31
user332474

最初の "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
)

編集:上記の例はcommand-promptから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---
25
Yogesh Mahajan

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

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

NB::あなたのファイル名やディレクトリ(例えば上記の例ではmyfile.txt)にスペースがある場合(例えば 'my file.txt'や 'c:\ Program Files')、 :

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

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

これが誰かに役立つことを願っています!

21

受け入れられた答えは良いですが、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行の長さの制限ですが、これを克服する方法はないようです。

14
jeb

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

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

これは私がフォルダ内のすべての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
9
mikej

NTファミリのWindows(シェルとしてcmd.exeを持つもの)をお持ちの場合は、 FOR/Fコマンド を試してください。

cmd.exe

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" } 

これは、for /F ...コマンドが数千行後に動かなくなる、200万行を超える250 MBのファイルで私にとってはうまくいきました。

foreachForEach-Objectの違いについては、 ForEachとForEach-Objectについて を参照してください。

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

2
mivk

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

フルコード はこちら

1
sendbits