LoginSignup
12
14

More than 5 years have passed since last update.

findコマンドで秒単位に新旧比較したい

Last updated at Posted at 2014-11-24

-mminはあっても-msecはないのか!

findコマンドは、様々な条件でファイル抽出ができて便利。でも時間の新旧で絞り込む機能は弱いと言わざるを得ない。

通常のタイムスタンプ(m:ファイルの中身を修正した日時)において、POSIXで規定されているのは-mtimeだけであり、しかも後ろには単純な数字しか指定できない。つまり現在から1日(=86400秒)単位での新旧比較しかできない。

  • 指定した年月日時分秒より新しい、より古い、等しい
  • n秒前より新しい、より古い、等しい

なんて比較はしたくてもできなかった。独自のオプションも使えばある程度できるけどOSによって使えたり使えなかったりするし……。さてどうしよう。

-newerオプションを活用するのが鍵

しかし-newerというオプションを使うと辛うじてこの悩みを解決できる。これは-newerの後ろで指定したファイルをとタイムスタンプ比較を行い、それよりも新しければ真とするという働きを持つオプションだ。

1.指定日時との比較

これを使えばまず、指定日時との比較は簡単にできる。

YYYY/MM/DD hh:flag_mm:ssよりも新しいファイルを抽出したいなら、こんなシェルスクリプトを書けばよい。

touch -t YYYYMMDDhhmm.ss thattime.tmp
find /TARGET/DIR -newer thattime.tmp
rm thattime.tmp

touchコマンドの書式の事情により、mmとssの間にピリオドを挿れないといけない点に注意してもらいたい。

次に「より古い」ものを抽出したいならどうするか。それには基準となる日時の1秒前(YYYYMMDDhhmms1とする)のタイムスタンプを持つファイルを作り、-newerオプションの否定形を使えばよい。

touch -t YYYYMMDDhhmm.s1 1secbefore.tmp # 基準日時の1秒前
find /TARGET/DIR \( \! -newer 1secbefore.tmp \)
rm 1secbefore.tmp

それでは「等しい」としたいならどうすればよいか。それには基準日時のファイルとその1秒前のファイルの2つを作り、「基準日時1秒前より新しい」かつ「基準日時を含むそれ以前」という条件にすればよい。

touch -t YYYYMMDDhhmm.ss thattime.tmp
touch -t YYYYMMDDhhmm.s1 1secbefore.tmp
find /TARGET/DIR -newer 1secbefore.tmp \( \! -newer thattime.tmp \)
rm 1secbefore.tmp thattime.tmp

2.n秒前より新しい、古い、等しい

基準日時との新旧比較のやり方がわかったのだから、あとは現在日時のn秒前、およびn-1秒前という計算ができれば実現できることになる。

それはどうやるのかといえば、シェルスクリプトで時間計算を一人前にこなすにて書いていた。そう、日常時間(YYYYMMDDhhmmss)をUNIX時間に変換して引き算し、それを元に戻せばいいのだ。そしてそのために、POSIXの範囲で動くコマンド"utconv"を自作していたのだ。

それでは、1分30秒前より新しい、等しい、古いファイルを抽出するシェルスクリプトを書いてみよう。

1分30秒前より新しいファイルを抽出
now=$(date '+%Y%m%d%H%M%S')
t0=$(echo $now                |
     utconv                   |
     awk '{print $0-60*1-30}' |
     utconv -r                |
     sed 's/..$/.&/'          )
touch -t $t0 thattime.tmp
find /TARGET/DIR -newer thattime.tmp
rm thattime.tmp
1分30秒前より古いファイルを抽出
now=$(date '+%Y%m%d%H%M%S')
t1=$(echo $now                |
     utconv                   |
     awk '{print $0-60*1-31}' |
     utconv -r                |
     sed 's/..$/.&/'          )
touch -t $t1 1secbefore.tmp
find /TARGET/DIR \( \! -newer 1secbefore.tmp \)
rm 1secbefore.tmp
ぴったりの1分30秒前のファイルを抽出
now=$(date '+%Y%m%d%H%M%S')
t0=$(echo $now                |
     utconv                   |
     awk '{print $0-60*1-30}' |
     utconv -r                |
     sed 's/..$/.&/'          )
t1=$(echo $now                |
     utconv                   |
     awk '{print $0-60*1-31}' |
     utconv -r                |
     sed 's/..$/.&/'          )
touch -t $t0 thattime.tmp
touch -t $t1 1secbefore.tmp
find /TARGET/DIR -newer 1secbefore.tmp \( \! -newer thattime.tmp \)
rm thattime.tmp 1secbefore.tmp
12
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
14