任意の日時のファイルを作りたい

ログのローテーションやfind -mtimeによる検索の動作を確認したい場合、更新日時が過去や未来のファイルが必要になる。touchコマンドの-dオプションを使うと、任意の日時のファイルを作成できる。

$ touch -d '2020-01-01 09:00:00' a.txt

$ ls -l --time-style=long-iso a.txt
-rw-r--r-- 1 root root 0 2020-01-01 09:00 a.txt

-dは既存ファイルにも適用でき、その場合はファイルの内容を変えずにタイムスタンプのみを書き換える。

日時の指定形式

-dにはGNU coreutilsのdate -dと同じ日付文字列を指定できる。年月日のみの指定や、タイムゾーン付きの指定も受け付ける。

$ touch -d '2026-08-10' b.txt

$ touch -d '2026-08-10T12:34:56+00:00' d.txt

$ ls -l --time-style=long-iso b.txt d.txt
-rw-r--r-- 1 root root 0 2026-08-10 00:00 b.txt
-rw-r--r-- 1 root root 0 2026-08-10 21:34 d.txt

年月日のみを指定した場合、時刻は00:00:00になる。

タイムゾーンを明示した場合はローカルタイムに変換して設定される。上記はJST環境での実行結果のため、+00:00の12:34が21:34になっている。

相対的な日時を指定する

-dの強みは「3日前」のような相対的な日時をそのまま書ける点にある。

$ date
Mon Aug 10 08:44:41 JST 2026

$ touch -d '3 days ago' c.txt

$ touch -d 'yesterday 15:00' c2.txt

$ ls -l --time-style=long-iso c.txt c2.txt
-rw-r--r-- 1 root root 0 2026-08-07 08:44 c.txt
-rw-r--r-- 1 root root 0 2026-08-09 15:00 c2.txt

agoを付けなければ未来の日時になる。有効期限切れの挙動を確認したい場合などに使える。

$ touch -d '3 days' future.txt

$ ls -l --time-style=long-iso future.txt
-rw-r--r-- 1 root root 0 2026-08-13 08:44 future.txt

日数を変数で扱いたい場合は、シェル変数を埋め込んだ文字列を渡す。

$ days=10
$ touch -d "$days days ago" old.log

指定できる日付文字列の詳細はdateコマンドで相対日付を計算する(date -d) を参照。

-t オプションとの違い

-tオプションでも日時を指定できるが、[[CC]YY]MMDDhhmm[.ss]の固定形式に限られる。

$ touch -t 202608101234.56 e.txt

$ ls -l --time-style=long-iso e.txt
-rw-r--r-- 1 root root 0 2026-08-10 12:34 e.txt

-tは区切り文字のない数値の羅列のため読みにくく、相対指定もできない。POSIXで規定された移植性の高い形式が必要な場合を除き、-dのほうが扱いやすい。

更新日時とアクセス日時を個別に設定する

-dだけを指定すると更新日時(mtime)とアクセス日時(atime)の両方が変わる。片方だけを変えたい場合は-mまたは-aを併用する。

$ touch -a -d '2021-01-01 00:00:00' f.txt

$ touch -m -d '2022-02-02 00:00:00' f.txt

$ stat f.txt
  File: f.txt
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: 2ch/44d	Inode: 6293033     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-01-01 00:00:00.000000000 +0900
Modify: 2022-02-02 00:00:00.000000000 +0900
Change: 2026-08-10 08:44:41.236091819 +0900
 Birth: 2026-08-10 08:44:41.236091819 +0900

ステータス変更日時(ctime)はtouch実行時の現在時刻になり、任意の値を設定できない。statコマンドの見かたはstatコマンドでファイルの詳細情報(inode・タイムスタンプ・権限)を表示する を参照。

他のファイルと同じ日時にする

-rオプションに基準となるファイルを渡すと、そのファイルのタイムスタンプをコピーする。日時を書き下す必要がない。

$ touch -r a.txt g.txt

$ ls -l --time-style=long-iso g.txt
-rw-r--r-- 1 root root 0 2020-01-01 09:00 g.txt

存在しないファイルを作らずに更新する

touchは指定したファイルが存在しない場合に空ファイルを作成する。-cオプションを付けると、存在しないファイルを無視してエラーにもしない。

$ touch -c -d '2020-01-01' nothing.txt
$ echo $?
0

$ ls nothing.txt
ls: cannot access 'nothing.txt': No such file or directory

既存ファイルのタイムスタンプだけを一括で書き換えたい場合、-cを付けておくとタイプミスによる空ファイルの生成を防げる。

具体例: find -mtime の動作確認

-dで日時をずらしたファイルを用意すると、削除処理やローテーション処理を実際に待たずに検証できる。

$ touch -d '10 days ago' old.log
$ touch -d '1 day ago' new.log

$ ls -l --time-style=long-iso
-rw-r--r-- 1 root root 0 2026-08-09 08:44 new.log
-rw-r--r-- 1 root root 0 2026-07-31 08:44 old.log

$ find . -type f -mtime +7
./old.log

7日より古いold.logのみが検索できている。-mtimeについては【find -mtime】指定日数より古い(新しい)ファイルを検索する を参照。

macOSでの注意点

macOS標準のtouch(BSD touch)にも-dは存在するが、受け付けるのはISO 8601形式(YYYY-MM-DDThh:mm:SS[.frac][tz])のみである。年月日だけの指定や相対指定はエラーになる。

$ /usr/bin/touch -d '2020-01-01T09:00:00' b1.txt

$ /usr/bin/touch -d '3 days ago' b2.txt
touch: out of range or illegal time specification: YYYY-MM-DDThh:mm:SS[.frac][tz]

GNU版と同じ書式を使いたい場合は、Homebrewでcoreutilsをインストールしgtouchコマンドを使用する。

$ brew install coreutils
$ gtouch -d '3 days ago' c.txt