先日、ちょっとした手元の作業中に、拡張子の最後に ".old" とつけてしまったファイル群のファイル名を元に戻したいということがありました。 Windows 上で。
ループ回して何かごにょごにょすればよさげなのは想像がつくものの、やり方がわからない。ググってもなかなかこれぞという情報に当たらない。 困ったときの twitter (以前は 困ったときのマイミク頼みでしたが、みんな twitter に移動してきてしまったので)ということで、つぶやいてみると、速攻で @UnoShintaro さんに for 文の使い方を教えてもらいました。
例: for %f in (*.old) do rename %f %~nf
片側だけに % を付ける変数なんてあるのかー、とか、 %~nf ってわけわかんないし、と思ったらもうひとつ "help" コマンドをおしえてもらいました。 "help for" で詳細情報出ます(この日記末尾に備忘として全文掲載)。 こういう作業は標準の DOS 上ではできないもんだと思いこんでいましたが、結構できるものですね。
C:\>help for 指定されたコマンドをファイル セットの各ファイルに対して実行します。 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 のような大 文字の変数を使うと読み取りやすく、大文字と小文字を区別しない修飾子 との混乱を避けることができます。