skip to Main Content

I have a program that takes in a csv file which stores data in this format ` Lastname,Name,YYYYMMDD` (last bit is year month day for birthday) that only accepts **only gregorian calendar years** and I want my program to display all files which corresponds to the input month (string of the name of the month).

For instance, if the input month is "May", my program should display all files that have 05 in the MM section of the birthday.

Can anyone please help explain what should I ?

#!/bin/bash
    echo "Enter csv file"
    read file
    echo "Enter month"
    read month
    cat "$file" | cut -f3 -d',' |    // this line seperates the csv file and focuses on the 3rd argument, which are the birthdays

3

Answers


  1. Seems like an ideal job for awk

    cat foo
    Lastname,Name,20230523
    foo,baz,20230117
    
    m=May
    awk -F, -vmonth=$m -f month.awk foo
    Lastname,Name,20230523
    

    month.awk is:

    BEGIN {
        months["Jan"] = "01";
        months["Feb"] = "02";
        months["Mar"] = "03";
        months["Apr"] = "04";
        months["May"] = "05";
        code = months[month];
    }
    
    substr($3,5,2) ~ code {print $0; }
    
    Login or Signup to reply.
  2. Using BASH:

    #!/bin/bash
    
    month=May
    target_csv=my.dat
    
    while read -r line ; do 
        d="${line##*,}"
        case "${d:4:2}" in
            01) mm=Jan ;;
            02) mm=Feb ;;
            03) mm=Mar ;;
            04) mm=Apr ;;
            05) mm=May ;;
            06) mm=Jun ;;
            07) mm=Jul ;;
            08) mm=Aug ;;
            09) mm=Sep ;;
            10) mm=Oct ;;
            11) mm=Nov ;;
            12) mm=Dec ;;
            *) echo "unknown month" && exit 1 ;;
        esac
    
        if [[ "$mm" == *"$month"* ]] ; then
            printf "%sn" "$line"
        fi
    done <"$target_csv"
    

    Another version of the script showing use of positional parameters and/or default values for month and target_csv:

    #!/bin/bash
    
    # You may pass the target month as positional parameter 
    # to script execution or will default to the value May and
    # You may pass the target csv file as the second positional 
    # parameter or will default to the value my.dat.
    # Example usage:  ./script_name May target.csv
    month="${1:-May}"
    target_csv="${2:-my.dat}"
    
    while read -r line ; do 
        d="${line##*,}"
        case "${d:4:2}" in
            01) mm=Jan ;;
            02) mm=Feb ;;
            03) mm=Mar ;;
            04) mm=Apr ;;
            05) mm=May ;;
            06) mm=Jun ;;
            07) mm=Jul ;;
            08) mm=Aug ;;
            09) mm=Sep ;;
            10) mm=Oct ;;
            11) mm=Nov ;;
            12) mm=Dec ;;
            *) echo "unknown month" && exit 1 ;;
        esac
    
        if [[ "$mm" == *"$month"* ]] ; then
            printf "%sn" "$line"
        fi
    done <"$target_csv"
    
    Login or Signup to reply.
  3. With GNU date(1) and grep(1), something like:

    #!/usr/bin/env bash
    
    read -rp "[Enter csv file]: " file
    read -rp "[Enter month]: " month
    
    [[ -z "$file" || -z "$month" ]] && {
      printf >&2 'file and month needs an input value!n'
      exit 1
    }
    
    [[ -e "$file" ]] || {
      printf >&2 "Cannot open `%s' (No such file or directory)n" "$file"
      exit 1
    }
    
    ##: Add more test if needed such as if the file is
    ##: A regular file and not a directory and so on...
    ##: readable by the user and so on...
    ##: See help test
    
    input_month="$(date -d "1$month" '+%m' 2>&1)" || {
      stat=$?
      printf >&2 '%sn' "${input_month/1}"
      exit "$stat"
    }
    
    grep "$input_month" "$file" || exit
    

    • See help test
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search