Amazon

2013年9月16日月曜日

同じ行を除外するシェル

sort/uniqコマンドで同じ行を除外することができます。 複数のファイルがあっても高速に処理することができるのですが、同じファイルに追記されるケースでは簡単に処理することができません。 そこで、名前をつけて呼び出すと、同じ日に発生した同じデータは一度だけ出力し2回めからは除外するシェルを作成しました。
#! /bin/sh
#
# uniq.sh: omit repeated lines by the day.
#
# Usage:
#  uniq.sh [queue file name] < input.txt
# Output:
#  ${BASEDIR}/queue/[queue file name].`date +%Y%m%d`.queue

# Arguments
QUEUENAME=${1:-queue}
QUEUEDIRNAME=${2:-queue}

# Pre-processing
BASEDIR=`dirname $0`
PROG=`basename $0`
TMPFILE=${BASEDIR}/tmp-${PROG}.$$
trap 'rm -f ${TMPFILE}; exit 1' 1 2 3 15

QUEUEDIR=${BASEDIR}/${QUEUEDIRNAME}
QUEUEFILE=${QUEUEDIR}/${QUEUENAME}-`date +%Y%m%d`.queue

# purge queue file or create queue directory
if [ -d ${QUEUEDIR} ]
then
    find ${QUEUEDIR} -mtime +7 -exec rm -f {} \;
else
    mkdir -p ${QUEUEDIR}
fi

# omit repeated lines by the day.
if [ -e ${QUEUEFILE} ]
then
    cat ${QUEUEFILE} > ${TMPFILE}
    cat ${QUEUEFILE} >> ${TMPFILE}
fi
sort | uniq >> ${TMPFILE}
sort ${TMPFILE} | uniq -u
sort ${TMPFILE} -uo ${QUEUEFILE}
 
# Post-processing
rm -f ${TMPFILE}

使い方

リダイレクトされたデータを行単位でソートして出力しますが、その日のうちに発生した同じ行は除外します。
$ echo aaa | ./uniq.sh 
aaa
$ echo aaa | ./uniq.sh 
$ echo bbb | ./uniq.sh 
bbb
$ echo bbb | ./uniq.sh 
$ 

なぜ作ったか

サーバの稼働監視でiostatやvmstatの出力やデータベースのセッション数を一定間隔毎にタイムスタンプ付きで出力していました。 せっかく収集している貴重なデータなのでzabbix_senderでzabbixに渡したかったのですが、データを作成しているシェルを修正することができなかったので、毎回同じファイルを加工してすでに送付済みのデータを除外し、新規のデータのみzabbix_senderに渡すことで対応できました。 同じ行の除外には、sort/uniqを使っていて早いです。 35行目の処理は、不要にも思えますがポイントとなります。

0 件のコメント: