ディレクトリタイムスタンプを最後に変更されたファイルに設定(再帰的)

ディレクトリタイムスタンプを最後に変更されたファイルに設定(再帰的)

埋め込みファイルの変更時間を反映するように、ディレクトリとそのディレクトリ内のすべてのサブフォルダのタイムスタンプをどのように変更できますか?

たとえば、次のディレクトリ構造を使用します。

[Jan 9]  root
├── [Jan 3]  file1
├── [Jan 7]  file2
├── [Jan 6]  sub1
│   ├── [Jan 2]  file3
│   └── [Jan 1]  file4
└── [Jan  4] sub2
    └── [Jan 8]  file5

以下は、このコンテンツを生成する1行のコードです。

mkdir -p root/sub1 root/sub2 && touch -d '2018-01-08' root/sub2/file5 && touch -d '2018-01-04' root/sub2/ && touch -d '2018-01-01' root/sub1/file4 && touch -d '2018-01-02' root/sub1/file3 && touch -d '2018-01-06' root/sub1/ && touch -d '2018-01-07' root/file2 && touch -d '2018-01-03' root/file1 && touch -d '2018-01-09' root/

それはリストできるtree -D

3つのディレクトリのタイムスタンプを次のように変更したいと思います。

[Jan 8]  root
├── [Jan 3]  file1
├── [Jan 7]  file2
├── [Jan 2]  sub1
│   ├── [Jan 2]  file3
│   └── [Jan 1]  file4
└── [Jan 8]  sub2
    └── [Jan 8]  file5

メモ:

  • ディレクトリの現在のタイムスタンプは完全に無視され、新しいタイムスタンプはコンテンツのみに基づいて設定されます。
  • タイムスタンプは、親ディレクトリの複数のレベルまで表示されます。

私がこれを行う理由は、rsyncを使用してディレクトリをコピーするためです。ディレクトリはgitにチェックインされ、リポジトリがチェックアウトされたどこでもrsyncdすることができます。 rsync がどこでも一貫して冪等性を持つようにするには、すべての項目のタイムスタンプと権限がわかっていることを確認する必要があります。すでにgitにコミットされている時間に基づいてファイルのタイムスタンプを設定するスクリプトがあります。また、すべてのファイルとディレクトリの権限を既知の状態に設定するスクリプトもあります。私が持っている唯一の問題は、ファイルから親ディレクトリへのバブリングタイムスタンプです。

ディレクトリの内容のタイムスタンプに基づいてディレクトリのタイムスタンプを設定するためにコマンドラインで実行できる1行または短いスクリプトが必要です。

ベストアンサー1

私が見過ごしていない限り(これを広くテストしていません):

find . -depth -type d -execdir \
    sh -c 'touch "$PWD/$0" -r "$PWD/$0/$( ls -t "$PWD/$0" | head -n 1 )"' \
    {} \;

できること:

  • すべてのサブディレクトリを探します。
  • 名前を学ぶ
  • を使用して、ls -t日付/時刻の逆順に内容を一覧表示し、最初の項目を取得します。
  • touch最新のオブジェクトをタイムスタンプとしてディレクトリをタッチする場合

正しい日付/時刻「バブリング」にこの-depthオプションを使用すると、サブディレクトリが処理されます。今後現在のサブディレクトリ(「深さ優先」)。サブディレクトリが処理され、対応する日付/時刻が更新されると、現在のディレクトリが処理されます(サブディレクトリの1つのタイムスタンプを継承できます)。

おすすめ記事