#!/bin/sh #xnecasr00 Roman Nečas #9.3.2024 export POSIXLY_CORRECT=yes # Function to display help message print_help() { echo "Usage: xtf [-h|--help] [FILTER] [COMMAND] USER LOG [LOG2 ...]" echo "" echo "Options:" echo "" echo " COMMAND can be one of these:" echo " list - displays records for the given user." echo " list-currency - displays sorted list of currencies." echo " status - displays account status for the given user." echo " profit - calculates profit for the given user." echo "" echo " FILTER can be a combination of:" echo " -a DATETIME - after: considers records after this date and time (exclusive)." echo " -b DATETIME - before: considers records before this date and time (exclusive)." echo " -c CURRENCY - considers records matching the given currency." echo "" echo " -h or --help displays this help message." } # Function to display error message and exit with code 1 print_error() { echo "Error: $1" >&2 exit 1 } # Function to validate date validate_date() { date -d "$1" >/dev/null 2>&1 || print_error "Invalid date: $1" } USER="" LOGS="" COMMAND="" AFTER_DATE="" BEFORE_DATE="" CURRENCY_FILTER="" # Process arguments while [ "$#" -gt 0 ]; do case $1 in -h|--help) print_help exit 0 ;; list|list-currency|status|profit) if [ -z "$COMMAND" ]; then COMMAND=$1 else print_error "Multiple commands provided" fi ;; -a) validate_date "$2" AFTER_DATE=$2 shift ;; -b) validate_date "$2" if [ -z "$BEFORE_DATE" ]; then BEFORE_DATE=$2 else print_error "Multiple 'before' dates provided. Please provide only one 'before' date." fi shift ;; -c) CURRENCY_FILTER=$2 shift ;; *) if [ -z "$USER" ]; then USER=$1 else # Use a special character to separate log files LOGS="$LOGS|$1" fi ;; esac shift done # Set default command (list) if none specified if [ -z "$COMMAND" ]; then COMMAND="list" fi # Check if user is specified if [ -z "$USER" ]; then print_error "No user specified." fi # Change IFS to handle log files with spaces OLD_IFS="$IFS" IFS="|" # Process logs for LOG in $LOGS do case "$LOG" in *.gz) zcat "$LOG" || print_error "Failed to read log: $LOG" ;; *) cat "$LOG" || print_error "Failed to read log: $LOG" ;; esac done # Restore IFS IFS="$OLD_IFS" # Filter records awk -v user="$USER" -v after="$AFTER_DATE" -v before="$BEFORE_DATE" -v currency_filter="$CURRENCY_FILTER" ' BEGIN { FS=";" } { if ($1 == "" || $2 !~ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$/ || $3 !~ /^[A-Z]{3}$/ || $4 !~ /^-?[0-9]+\.[0-9]{4}$/) { print "Error: Invalid record format: " $0 > "/dev/stderr" exit 1 } } $1 == user && ($2 > after || after == "") && ($2 < before || before == "") && ($3 ~ currency_filter || currency_filter == "") { print } ' | # Process command case "$COMMAND" in list) cat ;; list-currency) awk -F ";" '{print $3}' | sort -u ;; status) awk -F ";" '{ currency[$3] += $4 } END { for (cur in currency) { printf "%s : %.4f\n", cur, currency[cur] } }' | sort ;; profit) if [ -z "$XTF_PROFIT" ]; then XTF_PROFIT=20 fi awk -v profit="$XTF_PROFIT" -F ";" '{ currency[$3] += $4 } END { for (cur in currency) { if (currency[cur] > 0) currency[cur] = currency[cur] * (1 + profit / 100); printf "%s : %.4f\n", cur, currency[cur] } }' | sort ;; esac