154 lines
3.9 KiB
Bash
154 lines
3.9 KiB
Bash
#!/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
|
|
|