Windowsのコマンドプロンプトでtouchコマンド


Windowsのコマンドプロンプトでtouch

結論から言うと、なんか日本語で検索したときに出てくるtouchでは不十分なので、とりあえず新しいものを作ったというのが今回の内容です。
ソースコードは下。

touchがほしい

Linuxとかにあるtouchコマンドは、主に以下の挙動で使われているかと思います。

  • touch FILE でFILEが存在しない場合は空ファイルの作成。
  • 存在する場合は更新日時を変更。

これ何に使うの?っとかあるかもしれませんが、プログラマーにはちょっとした作業とかビルドイベント周りであると便利なコマンドです。

で、これはWindowsのコマンドプロンプトにはなく、上の作業を行ってくれる仮コマンドを作るということを、Microsoftが公式で記事にしています(サポート対象外になってますが、恐らくこれが発信源であるらしいことが書いてある)。

これによると、copyコマンドをバイナリで追加にして、読み込むファイルに対し空データを追加で書き込めば、ファイルの更新時間が書き換わるよね!っという理屈らしいです。

では、これを利用して、ファイルが存在しないときにはファイルを作る処理を入れて作り、実際に挙動を見てみます。

@echo off
if %1. ==. goto end
if not exist %1 (
    type nul > %1
) else (
    copy /b %1 +,, > nul
)

挙動の確認

フォルダの構造です。

  • A/
    • B/
    • touch.bat

Bフォルダにcdし、実際に挙動を確認しましょう。

次の手順です。

  • touchでb.txtを作成
  • touchで..\a.txtを作成
  • touchで..\a.txtを更新
>touch b.txt
>dir
A\B のディレクトリ
2017/05/08  09:26    <DIR>          .
2017/05/08  09:26    <DIR>          ..
2017/05/08  09:26                 0 b.txt
2017/05/08  09:26               101 touch.bat
>touch ..\a.txt
>dir
\A\B のディレクトリ
2017/05/08  09:26    <DIR>          .
2017/05/08  09:26    <DIR>          ..
2017/05/08  09:26                 0 b.txt
2017/05/08  09:26               101 touch.bat
>dir ..
\A のディレクトリ
2017/05/08  09:28    <DIR>          .
2017/05/08  09:28    <DIR>          ..
2017/05/08  09:28                 0 a.txt
2017/05/08  09:26    <DIR>          B
A\B>touch ..\a.txt
A\B>dir
\A\B のディレクトリ
2017/05/08  09:30    <DIR>          .
2017/05/08  09:30    <DIR>          ..
2017/05/08  09:28                 0 a.txt
2017/05/08  09:26                 0 b.txt
2017/05/08  09:26               101 touch.bat

なんと!上の階層に作ったa.txtが、b.txtと同じ階層にありますね!!!ふざけんなこら!!!!

なにこれ

どうやら、コマンドプロンプトのcopyでは書き込み先がない場合は同じ階層にあると仮定して動作(コピー)するということらしいです。

つまり同じ階層なら

  • b.txtが存在している。
  • b.txtを読み込んで空データを追加して、今の階層のb.txtに書き込もう。

で同じ階層じゃないなら

  • ..\a.txtは存在している。
  • * ..\a.txtを読み込んで空データを追加して、今の階層のa.txtに書き込もう。

っという挙動となります。

これではちゃんとtouchできないので、改良します。

新touch

以下が新touch.batです。

@echo off
if %1. ==. goto end
if not exist %1 (
    type nul > %1
) else (
    copy /b %1+,, %1 > nul
)

今回のcopyは「ファイルに対して空データを追加したものをファイルに書き込む」みたいな内容です。
とりあえずこれで一つ上の階層でもちゃんとtouchができます。

その他

コマンドプロンプトはちゃんと勉強してない上にする気もないので、上の内容だと大きいファイルとかだとあんまりよくない気もしてるんですが、そこらへんは特に実験してません(とりあえず自分で使う範囲ではこれで十分なので)。

もしコマンドプロンプトに詳しい方がいたら、さらに改良してもらえるととてもうれしいです。

最後に

ふぁっきゅーコマンドプロンプト

参考