dir でワイルドカードを使うと意図しないファイルがマッチする

dir コマンドの出力を使ったバッチファイルを作っていたところ、意図しないファイルが出力されていることに気づいた。「.csv」で終わるファイルのみを出力してほしいのだが、「.csv_header」で終わるファイルも出力されている。

> dir /b *.csv
1190.csv
1190.csv_header
shisetsu_toilet.csv
shisetsu_toilet.csv_header

原因

意図しないファイルにマッチする原因は MS-DOS や初期の Windows で使われていた 8.3 形式のファイル名にあった。ためしに 8.3 形式のファイル名も出力する「/x」オプションをつけて実行してみると、「.csv_header」というファイルが「...~1.csv」のように表現されていた。

> dir /x
…
2019/04/02  10:12             5,424              1190.csv
2019/04/02  10:35               939 1190~1.csv   1190.csv_header
2019/04/02  10:12         1,403,278 shiset~1.csv shisetsu_toilet.csv
2019/04/02  10:36               371 shiset~2.csv shisetsu_toilet.csv_header
…

dir コマンドではワイルドカードはこの 8.3 形式のファイル名にもマッチする。

解決方法 1 ― PowerShell を使う

Windows 7 からコマンドプロンプトに代わる新しいコマンドラインツールとして搭載された Windows PowerShell ではこの問題は発生しない。ただし別のプロセスからコマンドラインプログラムを呼び出すときはコマンドプロンプトが使用されてしまうため、この問題に対処できない。

解決方法 2 ― 8.3 形式のファイル名を生成しないようにする

コマンド側で 8.3 形式のファイル名にマッチさせない方法がないようなので、そもそも 8.3 形式のファイル名を生成させないことにした。

コマンドプロンプトまたは PowerShell を管理者として実行し、次のコマンドを実行する。

> fsutil 8dot3name set c: 1
8dot3name の生成が C: で無効になりました

8.3 形式のファイル名を削除する

設定はすぐに反映されるが、すでに生成された 8.3 形式のファイル名は削除されない。

コマンドプロンプトまたは PowerShell を管理者として実行し、次のコマンドを実行することで、カレントディレクトリ以下にあるファイルやフォルダの 8.3 形式ファイル名を削除できる。

> fsutil 8dot3name strip /v /s .