#!/bin/bash # grepByDates.sh - Filter log files on date range # (C) 2023 - F-Hauri.ch # Licensed by GNU GENERAL PUBLIC LICENSE Version 3 # This script: # - First use GNU "date" to convert user arguments to 'min' and 'max'. # - use "sed" to extract date from log lines # - use GNU "date" to convert string to UNIXTIME # - ask "bc" to make tests min < UNIXTIME < max, converting each line to 1 or 0 # - use "paste" to merge bc's outptut with original file, # - then finally, "sed" extract lines that begin by '1 ', while removing this. prog=${0##*/} usage() { cat <<-EOUsage Usage: $prog Each argument are required. Dates could by anything GNU date support: today, yesterday, now... EOUsage } die() { echo >&2 "ERROR $prog: $*"; exit 1 ;} # Convert user entries into UNIXTIME using 1 fork do GNU date { read -r start; read -r end ;} < <( date -f - +%s <<<"$1"$'\n'"$2" ) (($#==3))|| { usage;die 'Wrong number of arguments.';} [[ -f $3 ]] || die "File not found." # Read 1st line under bash for determining wich kind of log (apache vs system) read -r oline <"$3" # REGEX "bash" for system logs: 'Dec 01 01:23:45 ...' if [[ $oline =~ ^[^\ ]{3}\ +[0-9]{1,2}\ +([0-9]{2}:){2}[0-9]+ ]]; then # REGEX "sed" for system logs sedcmd='s/^\([^ ]\{3\} \+[0-9]\{1,2\} \+\([0-9]\{2\}:\)\{2\}[0-9]\+\).*/\1/' # REGEX "bash" for apache logs: '::1 - - [01/Dev/1812:01:23:45 +0000] ...' elif [[ $oline =~ ^[^\[]+\[[0-9]+/[^\ ]+/([0-9]+:){3}[0-9]+\ \+[0-9]+\] ]]; then # REGEX "sed" for apache logs sedcmd='s/^[0-9.]\+ \+[^ ]\+ \+[^ ]\+ \[\([^]]\+\)\].*$/\1/;s/:/ /;y|/|-|' else die 'Log format not recognized' fi # Finally run sed to extract lines that begin by '1' sed -ne s/^1\\o11//p <( # Merging bc's output with log file paste <( # bc will replace UNIXTIME by, if min < UNIXTIME < max then 1 else 0 bc < <( cat <<-EOInitBc define void f(x) { if ( ( $start < x ) && ( x < $end ) ) { 1;return ;}; 0; } EOInitBc # sed use pre-defined REGEX for extracting date from log file sed "$sedcmd" <"$3" | # date will convert date strings to "f(UNIXTIME)" for bc. date -f - +'f(%s)' ) ) "$3" )