1
\$\begingroup\$

This Bash program parses day, month, year and month and year from arguments:

#!/usr/bin/env bash

for arg
do
    day= month= year=
    case $arg in

    */*/*|*-*-*)
        read -r year month day <<< "$(date '+%Y %m %d' -d "$arg")"
        ;;

    ????/??|????/?)
        IFS='/' read -r -a arr <<< "$arg"
        month=${arr[1]} year=${arr[0]}
        ;;

    ????-??|????-?)
        IFS='-' read -r -a arr <<< "$arg"
        month=${arr[1]} year=${arr[0]}
        ;;

    ??/????|?/????)
        IFS='/' read -r -a arr <<< "$arg"
        month=${arr[0]} year=${arr[1]}
        ;;

    ??-????|?-????)
        IFS='-' read -r -a arr <<< "$arg"
        month=${arr[0]} year=${arr[1]}
        ;;

    esac

    echo "year: $year / month: $month / day: $day"

done

Usage:

./parse.sh 2021-03 2021-03-14 3/14/19 11/2019 2020/12
year: 2021 / month: 03 / day: 
year: 2021 / month: 03 / day: 14
year: 2019 / month: 03 / day: 14
year: 2019 / month: 11 / day: 
year: 2020 / month: 12 / day: 

It seems overly-verbose to me. Can I write it more succinctly?

\$\endgroup\$
5
\$\begingroup\$

How about

for arg do
    day= month= year=

    case $arg in
      */*/* | *-*-*)
          read -r year month day < <(date '+%Y %m %d' -d "$arg")
          ;;
      ????[-/]?? | ????[-/]?)
          IFS='-/' read -r year month <<< "$arg"
          ;;
      ??[-/]???? | ?[-/]????)
          IFS='-/' read -r month year <<< "$arg"
          ;;
    esac

    echo "year: $year / month: $month / day: $day"
done
  • remove pointless read into array
  • IFS can be more than one character
\$\endgroup\$
2
  • \$\begingroup\$ I was trying to combine the expressions, but failed. Thanks for the help. \$\endgroup\$
    – craig
    Dec 2 '21 at 22:14
  • 1
    \$\begingroup\$ Luckily glenn can express things that most others find very challenging. :) \$\endgroup\$
    – chicks
    Dec 3 '21 at 0:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.