for コマンド

Windows コマンドプロンプトでfor コマンドを使う。 for コマンドを使って、ファイルの操作を使う方法(覚書)

1.forfiles オプション

FORFILES [/P パス名] [/M 検索マスク] [/S]

[/C コマンド] [/D [+ | -] {yyyy/MM/dd | dd}]

 

説明

ファイル (または、ファイルのセット) を選んで、そのファイル上の

コマンドを実行します。これはバッチ ジョブの使用に便利です。

 

パラメーター一覧:

/P パス名 検索を開始するパスを示します。

既定のフォルダーは現在実行中の

ディレクトリ (.) です。

 

/M 検索マスク 検索マスクによってファイルを検索します。

既定の検索マスクは '*' です。

 

/S サブディレクトリに対しても処理を行うように forfiles に

指示します (例: "DIR /S")。

 

/C コマンド 各ファイルの実行するコマンドを示します。

コマンドの文字列は二重引用符で囲んでさい。

 

既定のコマンドは "cmd /c echo @file" です。

 

次の変数をコマンドの文字列に使用することができます:

@file - フィルの名前を返します。

@fname - 拡張子なしのファイル名を返します。

@ext - ファイルの拡張子だけを返します。

@path - ファイルの完全なパスを返します。

@relpath - ファイルの相対パスを返します。

@isdir - ファイルの種類がディレクトリの場合

は "TRUE"を、ファイルの場合は "FALSE" を返します。

@fsize - ファイルのサイズをバイトで返します。

@fdate - ファイルの最終更新日を返します。

@ftime - ファイルの最終更新時刻を返します。

 

コマンド ラインに特殊文字を使用する場合は、

文字を 16 進数コードで 0xHH 形式で (例:

タブは 0x09) 指定してください。CMD.EXE の

内部コマンドの前には "cmd /c" が必要

です。

 

/D 日付 最終更新日が指定された日かもしくはそれ

以降 (+)、または指定された日またはそれ

以前 (-) であるファイルを "yyyy/MM/dd" 形式を使っ

て選択します。または、最終更新日が現在

の日にちより "dd" 日あと、もしくは "dd" 日

前であるファイルを選択します。有効な "dd"

値は 0 から 32768 の間です。

指定がない場合は、"+" が既定で使用さ

れます。

/? ヘルプまたは使用法を表示します。

 

例:

FORFILES /?

FORFILES

FORFILES /P C:\WINDOWS /S /M DNS*.*

FORFILES /S /M *.txt /C "cmd /c type @file | more"

FORFILES /P C:\ /S /M *.bat

FORFILES /D -30 /M *.exe

/C "cmd /c echo @path 0x09 was changed 30 days ago"

FORFILES /D 2001/01/01

/C "cmd /c echo @fname is new since Jan 1st 2001"

FORFILES /D +2016/6/27 /C "cmd /c echo @fname is new today"

FORFILES /M *.exe /D +1

FORFILES /S /M *.doc /C "cmd /c echo @fsize"

FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"

 

2.for のオプション

forfiles コマンドのオプションとしては以下のようなものが
指定されたコマンドをファイル セットの各ファイルに対して実行します。
FOR %変数 IN (セット) DO コマンド [コマンドパラメーター]

%変数 単一文字の置き換え可能なパラメーターを指定します。
(セット) ファイル セットを指定します。ワイルドカードを使用できます。
コマンド 各ファイルごとに実行するコマンドを指定します。
コマンドパラメーター
指定されたコマンドのパラメーターまたはスイッチを指定します。
バッチ プログラムで FOR コマンドを使用するときは、%変数の代わりに、
%%変数を使用してください。変数名では大文字と小文字が区別されるため、
%i と %I は異なります。

コマンド拡張機能を有効にすると、次の FOR コマンドの追加形式
がサポートされるようになります:

FOR /D %変数 IN (セット) DO コマンド [コマンド パラメーター]

セットがワイルドカードを含む場合は、ファイル名ではなくディレクトリ名
の一致を指定します。

FOR /R [[ドライブ:]パス] %変数 IN (セット) DO コマンド [コマンド パラメーター]

[ドライブ:]パスから始めて、ツリーの各ディレクトリで FOR 文を実行し
ます。/R の後にディレクトリが指定されていない場合は、現在の
ディレクトリが使用されます。セットが単一のピリオド (.) である場合は、
ディレクトリ ツリーの列挙だけを行います。

FOR /L %変数 IN (開始,ステップ,終了) DO コマンド [コマンド パラメーター]

セットは、ステップの量ごとに変化する開始から終了までの数列です。
たとえば、(1,1,5) は 1 2 3 4 5、(5,-1,1) は (5 4 3 2 1) という数列に
なります。

FOR /F ["オプション"] %変数 IN (ファイル セット) DO コマンド
[コマンド パラメーター]
FOR /F ["オプション"] %変数 IN ("文字列") DO コマンド [コマンド パラメーター]
FOR /F ["オプション"] %変数 IN ('コマンド') DO コマンド [コマンド パラメーター]

または usebackq オプションの場合:

FOR /F ["オプション"] %変数 IN (ファイル セット) DO コマンド
[コマンド パラメーター]
FOR /F ["オプション"] %変数 IN ('文字列') DO コマンド [コマンド パラメーター]
FOR /F ["オプション"] %変数 IN (`コマンド`) DO コマンド [コマンド パラメーター]

ファイル セットは、1 つ以上のファイル名です。各ファイルが開かれ、
読み取られ、処理されてから、ファイル セットの次のファイルに進みます。
処理では、ファイルの読み取り、個々のテキスト行への分割と、0 個以上の
トークンへの解析が行われます。その後、見つかったトークン文字列を変数値に
設定して for ループの本体が呼び出されます。既定では、/F は、各ファイルの
各行から、空白で区切られた最初のトークンを取得して渡します。空白行は
スキップされます。既定の解析動作を変更するには、省略可能な "オプション"
パラメーターを指定します。これは、異なる解析オプションを指定する 1 つ以上の
キーワードを含む、引用符で囲まれた文字列です。キーワードは、次のとおりです:

eol=c - 行末のコメント文字を指定します (1 文字)。
skip=n - ファイルの先頭でスキップする行数を指定します。
delims=xxx - 区切り文字のセットを指定します。
これは、既定の区切り文字であるスペースとタブを
置き換えます。
tokens=x,y,m-n - 各繰り返しに対して、各行から for 本体に渡す
トークンを指定します。これにより、追加の変数名が
割り当てられます。
m-n の形式は範囲で、m 番目から n 番目の
トークンを指定します。
tokens= 文字列の最後の文字がアスタリスクである場合は、
追加の変数が割り当てられ、最後のトークンが解析された
後、行に含まれている残りのテキストを受け取ります。
usebackq - 次の新しい表示形式を指定します。
逆引用符で囲まれた文字列がコマンドとして実行され、
一重引用符で囲まれた文字列がリテラル文字列コマンドに
なり、ファイル セットのファイル名を二重引用符で
囲めるようになります。

例を参考にしてください:

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 で 3 番目以降のすべてのトークンを取得していることに
注意してください。
スペースを含むファイル名に対しては、二重引用符でファイル名を引用する
必要があります。
この方法で二重引用符を使うためには、usebackq オプションも
使わなければなりません。
使わなければ、二重引用符はリテラル文字列の定義として
解釈され、解析されます。

%i は for 文で明示的に宣言され、%j と %k は tokens= オプションで暗黙的に
宣言されています。
tokens= 行を使って 26 個までのトークンを指定できますが、
文字 'z' または 'Z' よりも高い変数を宣言することはできません。FOR 変数名は
単一の文字で、大文字と小文字を区別し、グローバルなものであり、一度に
アクティブにできるのは合計 52 個までです。

また、かっこで囲んだファイル セットを一重引用符で囲み、文字列にすることに
より、即時の文字列に対する FOR /F 解析ロジックを使うこともできます。
これは、ファイルからの単一入力行として処理されます。

最後に、FOR /F コマンドを使って、コマンド出力を解析することができます。
かっこの中のファイル セットを逆引用符で囲みます。この文字列は、コマンド
ラインとして子 CMD.EXE に渡されます。出力はメモリにキャプチャされ、
ファイルのように解析されます。
例:

FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i

この例は、現在の環境の環境変数名を列挙します。

また、FOR 変数参照の置換も拡張されました。
次のオプション構文を使うことができます:

%~I - すべての引用句 (") を削除して、%I を展開します。
%~fI - %I を完全修飾パス名に展開します。
%~dI - %I をドライブ文字だけに展開します。
%~pI - %I をパス名だけに展開します。
%~nI - %I をファイル名だけに展開します。
%~xI - %I をファイル拡張子だけに展開します。
%~sI - 展開されたパスは短い名前だけを含みます。
%~aI - %I をファイルの属性に展開します。
%~tI - %I ファイルの日付/時刻に展開します。
%~zI - %I ファイルのサイズに展開します。
%~$PATH:I - PATH 環境変数に指定されているディレクトリを
検索し、最初に見つかった完全修飾名に %I を
展開します。
環境変数名が定義されていない場合、または検索
してもファイルが見つからなかった場合は、この
修飾子を指定すると空の文字列に展開されます。

修飾子を組み合わせて、複合結果を得ることもできます:

%~dpI - %I をドライブ文字とパスだけに展開します。
%~nxI - %I をファイル名と拡張子だけに展開します。
%~fsI - %I を完全なパスと短い名前だけに展開します。
%~dp$PATH:I - PATH 環境変数に指定されているディレクトリを
検索して %I を探し、最初に見つかったファイル
のドライブ文字とパスだけに展開します。
%~ftzaI - %I を DIR コマンドの出力行のように展開します。

上の例の %I と PATH は、他の有効な値で置き換えることができます。
%~ 構文は、有効な FOR 変数名によって区切られます。%I のような大
文字の変数を使うと読み取りやすく、大文字と小文字を区別しない修飾子
との混乱を避けることができます。

3.一定サイズ以上になったファイルを移動する

echo off

rem 現在の日付を取得

set date_tmp=%date:/=%

set time_tmp=%time: =0%

set yyyy=%date_tmp:~0,4%

set yy=%date_tmp:~2,2%

set mm=%date_tmp:~4,2%

set dd=%date_tmp:~6,2%

set hh=%time_tmp:~0,2%

set mi=%time_tmp:~3,2%

set ss=%time_tmp:~6,2%

 

set sss=%time_tmp:~9,2%

set yday=%yyyy%%mm%%dd%_%hh%%mi%_%ss%%sss%

 

rem ログファイルは下記環境にあるものとします

rem ログファイル場所 D:\log\syslog.log

rem ログファイル退避場所 D:\log\bak

rem 10MB以上になったログファイルを退避させます。GTR 10485760 は10MB(バイト換算)

 

for %%A in (d:\log\syslog.log) do if %%~zA GTR 10485760 (goto A) else (goto chkErr)

:A

move D:\log\syslog.log D:\log\bak

ren D:\log\bak\syslog.log %yday%syslog.log

 

:chkErr

goto END

 

 

演算子 内容
EQU  等しい
NEQ  等しくない
GTR  より大きい
GEQ  以上
LEQ  以下
LESS  より小さい

 

4.一定数量以上になったファイルを移動する

以下を参考にしています
するのは失敗、何もしないのは、、


rem バッチファイル 10個以上の場合、削除
for /f "skip=10" %%a in ('dir /b /o-d *.log') do del %%a
rem コマンドプロンプト10個以上の場合、削除
for /f "skip=10" %a in ('dir /b /o-d *.log') do del %a

 

5.一定期間を経過した古いファイルを移動する

rem D:\data の下にある*.xmlファイルで120日前のファイルを、削除する
rem 対象ファイルは下記にあるものとし、変数alertに格納します
set alert=D:\Oracle\diag\tnslsnr\Oracle\listener\alert

rem %alert% の下にある*.zipファイルで120日前のファイルを削除する
FORFILES /P "%alert%" /S /M *.zip /D -120 /C "cmd /c del @file"

5.Oracle11g R2 のリスナーログファイルが一定サイズ以上になったらファイルを移動する

@echo off
rem 現在の日付を取得

for /F %%i in ('powershell (Get-Date^).ToString('yyyyMMdd_HHmm'^)') do (

set yday=%%i )

 
rem Oracle リスナー ログファイル(listener.log)は下記にあるものとし、変数traceに格納します
set trace=D:\app\Oracle\diag\tnslsnr\Oracleserve\listener\trace\
rem 対象ファイル listener.log
set ffile=listener.log
d:
cd %trace%
rem listener.log が50MB以上になる場合はファイルを移動します。
for %%A in (%trace%listener.log) do if %%~zA GTR 52428800 (goto A) else (goto chkErr)
:A
rem リスナーログファイルが50MB以上なので、リスナーサービスを一時的に停止します
lsnrctl set log_status off
rem リスナーログファイルを強制的にファイル名変更します
move %trace%listener.log %trace%%yday%_listener.log
rem 移動したリスナーログファイルをリネームします
ren %trace%baklistener.log %yday%listener.log
rem リスナーサービスを再起動します
lsnrctl set log_status on
:chkErr
goto END

:END



※注意:実施にあたってはじゅうぶんなテストを行ってください。
上記には記述していませんが、移動させたファイルを圧縮し、
一定期間を経過したら削除するなどすれば自動ローテーションが可能となります。
上記のようなバッチファイル作成し、タスクスケジューラに組み込み、
日曜日の早朝などOracleサーバOSを再起動するタイミングで実行できるように
スケジューリングしておきます。

 

 

6.for コマンド 指定フォルダ下 を圧縮

以下を参考にしています
for文(ファイル名・フォルダー名の取得)

rem ファイル名の一覧を取得

SET ATTFOL=D:\bat\test

SET SVNZP=C:\7z2201-extra\x64

for /d /r %ATTFOL% %%A in ( *.* ) do (
%SVNZP%\7za a %ATTFOL%\_attach.7z %%A
)