指定した日付のファイルを探すシェルスクリプト

いつにも増して集中力がないbonlifeです。最近ぼんやりと眺めさせていただいているid:parasporospaさんの日記にて「[unixtool]指定した日付のファイルを探す」という記事があり、こういうのをスクリプトにして自分用binに入れとくと便利かも!と思ってトライしてみました。findコマンドの-newerオプションとtouchコマンドでの指定日時のファイル生成を組み合わせてみました。(ワンライナーじゃない全く普通のシェルスクリプトです。)

  • find_by_date
#! /bin/sh

# シグナルをトラップして一時ファイル削除

trap 'rm -f /tmp/tmp_*.$$; exit 1' 1 2 3 15

SCRIPT_NAME=`basename $0`

# エラー終了関数定義

function error_exit {
    echo "$SCRIPT_NAME [path] [CCYYMMDD]" >&2
    rm -f /tmp/tmp_*.$$
    exit 1
}

# 引数の数をチェック

if [ $# -ne 2 ];
then
    error_exit
fi

SEARCH_PATH=$1
DATE=$2

# $DATEが8桁の数字であるかの簡易チェック

if [ -z "`echo $DATE | egrep '[0-9]{8}'`" ];
then
    error_exit
fi

# 指定日時のFROM、TOを取得
# 前日の23:59:59から当日の23:59:59まで

DATE_FROM=`date --date "${DATE} 1 second ago" +%Y%m%d%H%M.%S
# DATE_FROM=${DATE}0000.00
DATE_TO=${DATE}2359.59

# touchで指定日時の空ファイルを作成

touch -t $DATE_FROM /tmp/tmp_date_from.$$
touch -t $DATE_TO   /tmp/tmp_date_to.$$

# findの-newer(とその否定)を使い、一時ファイルと比較した結果を出力 (ls)

find $SEARCH_PATH -type f -newer /tmp/tmp_date_from.$$ ! -newer /tmp/tmp_date_to.$$ -ls;

# 一時ファイルの削除

rm -f /tmp/tmp_*.$$

これでそれっぽい動きをするシェルが出来ました。ただ、これAIXでは動かないのです。GNU版Dateじゃないと"1 second ago"なんて小粋なことは出来ないわけで。で、仕方なしに妥協してコメントアウトしてある行を使うと、タイムスタンプが対象日の00時00分00秒のファイルは検索に引っかからなくなってしまう罠。シェルで文字列をごにょごにょして日付計算するのはかなり面倒なので却下。PerlワンライナーでlocaltimeやTime::Localのtimelocalを使って無理矢理やろうかとも思ったのですが、それなら全部Perlで書いた方が良いじゃないの…ということで。後でPerlで書き直してみようっと。
本日の結論としては、findとtouchの連携は結構便利!