読者です 読者をやめる 読者になる 読者になる

argius note

プログラミング関連

開発しています



ペアの2ファイル間でタイムスタンプをコピー

Unix-like Perl

見出しがちょっと分かりづらいかも知れませんね。
例えば、ディレクトリAとBの下に同じファイル名だけどタイムスタンプの異なる一連のファイルがあって、AとBのファイルのタイムスタンプを同じにしたりする方法です。複数ファイルの改行コードをCRLF→LF変換 - argius noteでもちょっと触れています。
cpなら-pオプションを付ければよろしいわけですが、コピーの後で変更されたタイムスタンプを元に戻すような場合にはこの方法があります。


まずは、touchコマンドの-rオプションを使います。これは、ファイルのタイムスタンプを現在時刻の代わりに指定したファイルのタイムスタンプのものを使うように指示する*1オプションです。

次に、ファイル群の巡回方法です。
同じディレクトリに、".bak"とか".orig"とかで存在している場合は、Perlで改行コード変換で紹介しているfindを使う方法が楽です。

$ find . -name "*.txt" -exec touch -r {}.bak {} \;

但し、findの-execオプションは、毎回プロセスを作るので遅いです。
Perlのone-liner(一行野郎)を使うのに慣れているなら、こうした方がおそらく高速です。

$ find . -name "*.txt" | perl -ne 'chomp; utime time, (stat "$_.orig")[9], $_'

これなら、findでなくても、lsコマンドや、forを使った方法でも応用できますし、細かい指定も可能になります。最初に挙げた、ディレクトリAとBのケースの場合は、こうなります。

$ ls A/*.txt | perl -ne 'chomp; $src=$_; s/^A/B/; utime time, (stat $src)[9], $_'

Windowsの場合は、chompでつまづくことがあるかも知れません。その場合は、chompが役に立たない - くれすのPerl日記 - Hatena::Group::Perlなどを読んで見ると良いかもです。

*1:GNU版のhelpでは"use this file's times instead of current time"となっています。