連載
» 2001年04月27日 00時00分 UPDATE

Windows 2000 活用講座 Windows 2000 コマンドライン徹底活用:第7回 forコマンド(その1) (2/3)

[塩田紳二,著]

“~”―ダブルクォート記号の除去

 まず、単に“~”のみを記述したときには、%Vに含まれているダブルクォート記号が除去される(例:「"C:\Program Files\Internet Explorer\IEXPLORE.EXE"」が「C:\Program Files\Internet Explorer\IEXPLORE.EXE」となる)。%%V内にダブルクォートが含まれていなければ、%%Vそのままが返される。実際、他のオプションを指定したときでもこの指定は暗黙的に行われていることになるため、すべてダブルクォートが除去された形で展開される。また、除去するダブルクォートは指定文字列全体をくくるもののみで、文字列の途中にダブルクォートが含まれていても除去されないし、セット中の指定でダブルクォートが正しく対になっていないとforステートメント全体がおかしくなることがあるので、注意が必要だ。

“s”―短い形式の名前指定

 “s”は、%%Vのフルパスを8.3形式で表現したものだ。これは、ファイル名や途中のフォルダ名に長いファイル名があった場合、いわゆる“短い形式”に変換される。

“a”―ファイル属性の表示

 “a”は、ファイルの各属性をアルファベット1文字で表したもので、全部で9文字分の長さの文字列が返される。この9文字がそれぞれ何を意味するのかについての記述はヘルプファイルなどにはないので、手元でテストしてみたところ

drahsc---

という文字列が返されるようである。この6つの文字はそれぞれ次のような意味がある。

文字 意味
  d (Directory) ディレクトリ
  r (Read Only) 読み取り専用
  a (Archive) アーカイブ
  h (Hidden) 隠しファイル/隠しディレクトリ
  s (System) システム ファイル
  c (Compact) 圧縮

 しかしここまでは判明したが、暗号化(エクスプローラでは“E”で表される)やインデックス化対象のフラグは表示されなかった。つまり残りの3つ分は不明ということである。Windows 2000における属性は、APIのレベルでは次のような13種類がある。

属性 意味
アーカイブ ファイルに書き込みを行うと自動的にセットされ、バックアップソフトウェアなどがバックアップの対象ファイルを見つけるために使われる
圧縮 内容を圧縮して、ディスク領域を節約する
暗号化 内容を暗号化して、データをセキュリティで保護する
インデックス化 検索を速くするために、ファイルにインデックスを付ける
オフラインフォルダ ノートPCなどのにファイルをコピーして同期させ、オフラインでも利用可能にする
隠しファイル 一般ユーザーには見えないようにファイルを隠す
システム システムで利用する重要なファイル
スパースファイル ファイル・サイズは非常に大きいが、そのごく一部分にしかデータが含まれていないファイル
デバイス 物理的なデバイスを表すファイル
ディレクトリ フォルダ
テンポラリ 一時ファイル
読み取り専用 書き込み不可能なファイル
リパースポイント フォルダのリダイレクト(シンボリックリンク/マウント機能)
Windows 2000におけるファイル属性

 この13種類のうち、6つは先ほど説明したとおりである。残り7つのうち、暗号化とインデックス化は表示されず、デバイスもNUL(nullデバイス)やCON(コンソール・デバイス)を指定してみたが表示されることはなかった(%%~aVが空の文字列になる)。残りあと4つのうち3つが表示される可能性があるが、設定してあっても表示されないという可能性もあるし、何らかのバグで、本来表示されるべき暗号化属性は表示されない可能性もある。いずれにしろ、attribコマンドでも設定できる、最も頻繁に使うと思われる属性はカバーされているので、これでも十分だろう。なおセット中におけるワイルドカード指定では、隠し属性のついたファイルやディレクトリは列挙されないので、そのようなファイルを使いたければ、ファイル名を直接指定する必要がある。

“%%~$環境変数名:V”―ファイルの検索

 “%%~$環境変数名:V”は、%%Vが指定するファイル名を環境変数に定義されているパスのリストから検索して、最初に見つかったパスをフルパスとして展開するものである。環境変数は、Path環境変数のようにパスをセミコロンで区切って記述する。例えば、

SET TEST=C:\;C:\CMD;C:\TEMP

となっている、%%Vの内容が“test.txt”だとすると、“%~$TEST:V”は、

C:\CMD\test.txt

などのようになる(C:\CMDにtest.txtがある場合)。この表記方法を使えば、いくつかのディレクトリのどこかにあるファイルをフルパスで見つけられるようになる。また環境変数名としてPathを使えば、コマンドプロンプトで(パス指定をせずに)実行されるコマンドのフルパス名を見つける、といった使い方もできる。

 この展開で注意すべき点は、実際に存在しないファイル名を指定してしまったときには、カレントフォルダのパスなどが返されることだ。ワイルドカードを使ったセットの指定ならば問題はないが、ワイルドカードを含まない文字列を直接指定してしまったときには、このような問題が起こりうる。

 実際にプログラムを動かして試してみよう。

@echo off
for %%V in ( *.* ) do  ( echo -----------------------------------
echo Normal  = %%V
echo DelQ    = %%~V
echo Fullpath= %%~fV
echo Drive   = %%~dV
echo Path    = %%~pV
echo Name    = %%~nV
echo Ext     = %%~xV
echo Drv Path= %%~dpV
echo Short N = %%~sV
echo Attrib  = %%~aV
echo Date    = %%~tV
echo Size    = %%~zV
echo Search p= %%~$Path:V
)

 このようにすると、カレント・ディレクトリのファイルに対して、さまざまに展開したものが表示されるはずである。ここで2行目の括弧の中にある“*.*”を“aaaa”という文字列に変更して実行すると次のようになる(“aaaa”というファイルはカレントディレクトリにないものとする)。

-----------------------------------
Normal  = aaaa
DelQ    = aaaa
Fullpath= C:\cmd\forcommand\aaaa カレントフォルダでパスが作られる
Drive   = C:
Path    = \cmd\forcommand\
Name    = aaaa
Ext     =
Drv Path= C:\cmd\forcommand\
Short N = C:\cmd\FORCOM~3\aaaa
Attrib  =
Date    =
Size    =
Search p=

 このように、まるで“C:\cmd\forcommand\aaaa”というファイルがあるかのように見えてしまうので、注意が必要である。もし間違えて処理を続けると、エラーが発生してしまうだろう(必要ならば、ファイルが存在しているかどうかをifステートメントなどで確認してから処理を続行する必要があるかもしれない)。

 次に文字列をいろいろ指定して他の展開結果を見てみよう。

@echo off
set TEST=C:\;C:\CMD;c:\temp;C:\cmd\forcommand
for %%V in ( y.txt xcopy.exe "backupD.cmd" ) do  ( echo -----------------------------------
echo Normal  = %%V
echo DelQ    = %%~V
echo Fullpath= %%~fV
echo Drive   = %%~dV
echo Path    = %%~pV
echo Name    = %%~nV
echo Ext     = %%~xV
echo Drv Path= %%~dpV
echo Short N = %%~sV
echo Attrib  = %%~aV
echo Date    = %%~tV
echo Size    = %%~zV
echo Search T= %%~$TEST:V
echo Search P= %%~$PATH:V
)

 このスクリプトを実行すると(3種類のパラメータを使って、変数の展開を実行している)、以下のような結果が得られる。

C:\cmd\forcommand>ptest05.cmd
-----------------------------------
Normal  = y.txt
DelQ    = y.txt
Fullpath= C:\cmd\forcommand\y.txt カレントディレクトリで返される
Drive   = C:
Path    = \cmd\forcommand\
Name    = y
Ext     = .txt
Drv Path= C:\cmd\forcommand\
Short N = C:\cmd\FORCOM~3\y.txt
Attrib  =
Date    =
Size    =
Search T= C:\cmd\y.txt 正しいパスが見つかる
Search P=
-----------------------------------
Normal  = xcopy.exe
DelQ    = xcopy.exe
Fullpath= C:\cmd\forcommand\xcopy.exe
Drive   = C:
Path    = \cmd\forcommand\
Name    = xcopy
Ext     = .exe
Drv Path= C:\cmd\forcommand\
Short N = C:\cmd\FORCOM~3\xcopy.exe xcopy.exeの本当の位置
Attrib  =
Date    =
Size    =
Search T=
Search P= C:\WINNT\system32\xcopy.exe
-----------------------------------
Normal  = "backupD.cmd" ダブルクォートでくくられている
DelQ    = backupD.cmd ダブルクォートがない
Fullpath= C:\cmd\forcommand\backupD.cmd 以下もダブルクォートがない
Drive   = C:
Path    = \cmd\forcommand\
Name    = backupD
Ext     = .cmd
Drv Path= C:\cmd\forcommand\
Short N = C:\cmd\FORCOM~3\backupD.cmd
Attrib  =
Date    =
Size    =
Search T= C:\cmd\backupD.cmd
Search P=

“d”、“p”、“x”―ドライブ名、パス名、拡張子の取り出し

 “d”(ドライブ名)、“p”(パス)、“x”(拡張子)といった部分を取り出す場合、それぞれ、表記のための記号も用意されている。例えばドライブ指定であれば、“C:”のようにコロン記号の付いたものとなる。このため、各部分をそのまま使って、フルパスを構成することが可能だが、逆にドライブを判断するような場合には、コロンやピリオド(拡張子の区切り)やパス名の最後の“\”が含まれていることを考慮して条件判断などを行う必要がある。

 なお、パス名がUNC表記(ファイル/ディレクトリ名表記にサーバ名も含めて、ネットワーク上のリソースを一意に表すための表記方法)の場合は、“d”や“p”の指定は通常のローカルのドライブ上の場合とは異なるので注意が必要である。例えば“%%V”が“\\server\shared\test.txt”ならば、ドライブ名とパス名はそれぞれ“\\”と“server\shared\”というふうになる(パス名の先頭には“\”がない)。

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。