DEV Community

Query Filter
Query Filter

Posted on

filtered7

#!/bin/bash
# Usage: cat file.csv | ./filter_lastNdays.sh 4 45 "~"

if [[ -z "$1" || -z "$2" ]]; then
    echo "Usage: $0 <date_column> <days_back> [delimiter]"
    exit 1
fi

DATE_COL="$1"
DAYS="$2"
DELIM="${3:--}"          # default delimiter is ~

# THIS WAS THE MAIN BUG → must go BACK in time!
CUTOFF=$(date -d "$DAYS days ago" +%s)

awk -v col="$DATE_COL" -v cutoff="$CUTOFF" -F"$DELIM" '
function month2num(m) {
    return (index("JanFebMarAprMayJunJulAugSepOctNovDec", toupper(m)) + 2) / 3
}
{
    if (NF < col) { next }                     # not enough fields → skip

    d = $col
    sub(/:[0-9]{3}/, "", d)                    # remove milliseconds safely

    # Example input: Jul 11 2019  2:22:57PM  or  Jul 11 2019 2:22:57 PM
    if (match(d, /^([A-Za-z]{3})[[:space:]]+([0-9]{1,2})[[:space:]]+([0-9]{4})[[:space:]]+([0-9]{1,2}):([0-9]{2}):([0-9]{2})[[:space:]]*(AM|PM)/, a)) {
        mon   = month2num(a[1])
        mday  = a[2] + 0
        year  = a[3] + 0
        hour  = a[4] + 0
        min   = a[5] + 0
        sec   = a[6] + 0
        ampm  = a[7]

        if (ampm == "PM" && hour < 12) hour += 12
        if (ampm == "AM" && hour == 12) hour = 0

        ts = mktime(year " " mon " " mday " " hour " " min " " sec)
        if (ts >= cutoff) print $0
    }
    # if no match → silently skip the line
}
'
Enter fullscreen mode Exit fullscreen mode

Top comments (0)