「mv で日付付きにリネームしたら、`date` の展開がうまくいかなかった」
Linuxサーバーを運用していると、必ず一度はこの場面にぶつかります。
この記事では、Linuxで
date コマンドと mv/cp を組み合わせて、ファイル名に日付を付けてリネームする実践的な手順を解説します。バッククォートと
$() の使い分け、年月日時分秒まで含めるフォーマット、運用ルールとしての書き戻し手順、よくある落とし穴までを一通りまとめました。この記事のポイント
・mv file.txt file.txt_$(date +%Y%m%d) で日付付きファイル名にリネームできる
・date +%Y%m%d は「20111217」形式、+%Y%m%d_%H%M%S なら秒まで一意化
・バッククォート ` と $() はどちらでも動くが、現代のシェルでは $() 推奨
・設定ファイル変更前のバックアップ運用ルールとしてセットで覚えておく
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜファイル名に日付を付けるのか(背景・運用ルール)
サーバー管理の現場では、設定ファイルを変更する前に必ずバックアップを取るルールが敷かれます。理由はシンプルで、変更後に何らかのトラブルが起きたとき、すぐに元へ戻すためです。
このとき重要になるのが「いつ取ったバックアップか」を残しておくことです。
同じ
httpd.conf でも、3ヶ月前のものと先週のものでは中身が違います。ファイル名に日付を含めておけば、後から見返したときに変更履歴がそのまま時系列で並びます。
私が現役で関わってきた現場では、設定変更の運用ルールが次のように決まっていました。
・変更前ファイルは削除せず、必ず保存する
・保存名は「元のファイル名 + 日付」
・戻す可能性が消えるまで、過去日付分も削除しない
このルールがあると、過去に何度も触ったファイルは
httpd.conf_20240315、httpd.conf_20240620、httpd.conf_20251101 のように、日付違いの履歴が並びます。障害発生時に「先月の月初に戻したい」と言われても、ファイル一覧を
ls -l するだけで戻すべきファイルが特定できる、という運用上の安心感が得られます。ここで使うのが
date コマンドと、シェルのコマンド置換($() またはバッククォート)の組み合わせです。date コマンドで日付を取り出す
1. 現在の日時を表示する
まずはdate コマンドを引数なしで実行すると、現在のシステム日時が表示されます。$ date 2011年 12月 17日 土曜日 00:11:21 JST
このままではファイル名に使うには長すぎるので、フォーマット指定子で必要な部分だけを取り出します。
2. 年月日だけを8桁の数字で取り出す
date コマンドの引数に +書式 を渡すと、任意の形式で出力できます。$ date +%Y%m%d 20111217
%Y=4桁年」「%m=2桁月」「%d=2桁日」を連結した形です。ファイル名に付けるには、この「20111217」がそのまま使えます。
桁数を揃えるために
%m・%d は常にゼロ埋め2桁で出力されるので、文字列としてのソート順が日付順と一致します。これは ls で並べたときの可読性に直結します。ファイル名に日付を付けてリネームする
1. mv コマンドで日付付きにリネームする
それではdate の出力をファイル名の一部に埋め込みます。$ touch file_test.txt ←touchコマンドで「file_test.txt」ファイルを作る。 $ ls -l ←ファイルの情報を表示する。 -rw-rw-r-- 1 pakira pakira 0 12月 17 00:16 file_test.txt $ mv file_test.txt file_test.txt_`date +%Y%m%d` ←dateコマンドを実行する。 $ ls -l file_test.txt* ←ファイル名が変わっていることを確認する。 -rw-rw-r-- 1 pakira pakira 0 12月 17 00:18 file_test.txt_20111217
`date +%Y%m%d` の部分です。バッククォート ` で括られた部分は、シェルが先にコマンドとして実行し、その結果(標準出力)に置き換えてから
mv に渡されます。つまりシェルから見ると、最終的に実行されているのは次のコマンドです。
$ mv file_test.txt file_test.txt_20111217
hostname・whoami・uname -r など、出力を文字列として埋め込みたい場面で広く使われます。2. $() を使った同等の書き方
バッククォートは Shift+@ で入力しますが、見た目がシングルクォート(')と紛らわしく、ネストもできません。そのため、現代のシェル(bash/zsh)では
$() が推奨されます。$ touch file_test2.txt_$(date +%Y%m%d) $ ls -l file_test2.txt* -rw-rw-r-- 1 pakira pakira 0 12月 17 00:31 file_test2.txt_20111217
`...` と完全に同等です。スクリプトに書く場合は
$() のほうが読みやすく、入れ子も可能(例:$(date +%Y%m%d_$(hostname)))なため、新しく書くコードは $() で統一することを推奨します。3. 上書きを防ぐ cp -i / mv -i の併用
日付までの精度でリネームしていると、同じ日に2回バックアップを取った場合に既存ファイルを上書きしてしまうリスクがあります。これを防ぐのが
-i(interactive、対話モード)オプションです。$ cp -i httpd.conf httpd.conf_$(date +%Y%m%d) cp: 'httpd.conf_20111217' を上書きしますか? n
スクリプトに組み込む場合は、後述の
%H%M%S まで含める形式と組み合わせると、確認プロンプトを使わず一意化できます。date フォーマット指定子の早見表
ファイル名に使える主要な書式は次のとおりです。組み合わせて使うことで、年月日だけでなく時分秒まで含めた一意なファイル名を作れます。
| 書式 | 説明 | 出力例 |
|---|---|---|
%Y |
年(4桁表記) | 2026 |
%y |
年(2桁表記) | 26 |
%m |
月(01~12) | 05 |
%d |
日(01~31) | 18 |
%H |
時(00~23) | 14 |
%I |
時(00~12) | 02 |
%M |
分(00~59) | 30 |
%S |
秒(00~59) | 45 |
%a |
曜日(Sun~Sat) | Sun |
%b |
月名(Jan~Dec) | May |
上記を参考に
date +%Y%m%d_%H%M%S と実行すれば「20111217_003145」のように年月日時分秒まで取り出せます。1日に何度もバックアップを取る場合でも、秒まで含めれば実質的にファイル名が衝突することはありません。
応用:ディレクトリ単位のバックアップとスクリプト化
1. ディレクトリごと日付付きでアーカイブ
ファイル単体ではなく、設定ディレクトリ全体をtar.gz で固める運用もよく使われます。$ tar czvf /backup/etc_$(date +%Y%m%d).tar.gz /etc $ ls -l /backup/ -rw-r--r-- 1 root root 12345678 5月 18 14:30 etc_20260518.tar.gz
cron に登録すれば日次バックアップとして即運用できます。2. シェル変数に格納して使い回す
1つのスクリプト内で何度も同じ日付文字列を使う場合は、シェル変数に入れておくと一貫します。#!/bin/bash TODAY=$(date +%Y%m%d) cp /etc/httpd/conf/httpd.conf /backup/httpd.conf_${TODAY} cp /etc/nginx/nginx.conf /backup/nginx.conf_${TODAY} echo "バックアップ完了: ${TODAY}"
3. find + xargs で古いバックアップを掃除する
日付付きで蓄積していくと、いずれディスクが逼迫します。30日より古いバックアップを自動削除する場合は
find の -mtime と組み合わせます。$ find /backup -name "*.tar.gz" -mtime +30 -print $ find /backup -name "*.tar.gz" -mtime +30 -delete
-print で対象を確認してから -delete に切り替えると、誤削除を防げます。トラブルシュート・よくある落とし穴
1. 「date: extra operand」が出る
date +%Y %m %d のようにスペースを入れてしまうと、%m 以降が別の引数と解釈されてエラーになります。書式指定子は 1つの引数として連続した文字列で渡す のがルールです。
区切りたい場合は
date +%Y-%m-%d のように、ハイフンやアンダースコアでつなぎます。2. バッククォートがコピペで化ける
ブログやチャットからコマンドをコピペすると、バッククォート ` が別のクォート記号に置き換わっていることがあります。こうなると見た目は似ていてもシェルがバッククォートとして認識せず、ファイル名がそのまま
'date +%Y%m%d' のような文字列としてくっついてしまいます。コピペで挙動が怪しいときは、
$() 形式で書き直すと回避できます。3. ロケールで月名が日本語になる
date +%b でロケールが ja_JP.UTF-8 の環境では「5月」と日本語の月名が出ます。ファイル名に使うとマルチバイト文字がそのまま入り、後続のスクリプトや別環境で扱いづらくなります。
英字の月名で固定したい場合は
LC_ALL=C date +%b のように一時的にロケールを切り替えます。4. cron で実行すると環境変数が違う
対話シェルでは動いた$(date +%Y%m%d) が、cron から呼ぶスクリプトで空文字になる…という相談を受けることがあります。原因の多くは
cron 配下では PATH や LANG が最小限になっているためです。スクリプト冒頭で
PATH=/usr/local/bin:/usr/bin:/bin を明示する、もしくは /usr/bin/date とフルパスで書くことで解消します。本記事のまとめ
日付付きファイル名は、設定変更の前後比較・障害対応・バックアップの世代管理を一気通貫で支える小さくて強力なテクニックです。特にサーバー管理の現場では、「変更履歴を残す」というルールと相性が良く、覚えておくと一生使えます。
| やりたいこと | コマンド |
|---|---|
| 現在の日時を表示する | date |
| 年月日8桁を取り出す | date +%Y%m%d |
| 年月日時分秒を取り出す | date +%Y%m%d_%H%M%S |
| ファイル名に日付を付けてリネーム | mv file.txt file.txt_$(date +%Y%m%d) |
| ファイル名に日付を付けてコピー(上書き確認付き) | cp -i file.txt file.txt_$(date +%Y%m%d) |
| ディレクトリを日付付きでアーカイブ | tar czvf /backup/etc_$(date +%Y%m%d).tar.gz /etc |
| 30日より古いバックアップを削除 | find /backup -name "*.tar.gz" -mtime +30 -delete |
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:/proc/scsi/scsiでSCSIデバイス情報を確認する方法|ホストアダプタの接続状況を調べる
- 前のページへ:Linuxのロードアベレージを確認・理解する方法|uptimeとwの出力と高負荷時の原因特定
- この記事の属するカテゴリ:Linuxtipsへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます