\$\begingroup\$
\$\endgroup\$
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?
Toby Speight
87.3k14 gold badges104 silver badges322 bronze badges
1 Answer 1
\$\begingroup\$
\$\endgroup\$
2
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
answered Dec 2, 2021 at 21:54
-
\$\begingroup\$ I was trying to combine the expressions, but failed. Thanks for the help. \$\endgroup\$craig– craig2021年12月02日 22:14:29 +00:00Commented Dec 2, 2021 at 22:14
-
1\$\begingroup\$ Luckily glenn can express things that most others find very challenging. :) \$\endgroup\$chicks– chicks2021年12月03日 00:13:44 +00:00Commented Dec 3, 2021 at 0:13
lang-bash