You gave a link to the source of the special code. Beneath the code you find the comment:
Note that this doesn't iterate over each element in the array separately... instead it simply concatenates the array and matches "two" as a substring. This could cause undesirable behavior if one is testing whether the exact word "two" is an element in the array. @MartyMacGyver Aug 19 '13 at 23:21
Another explanation.
Try the following commands to see what is happening (or use set -x
):
echo case "${leap_yrs[@]}" in *"${year}"*
if [[ "1852 1856 1860 1864 1868 1872 1876 1880 1884 1888 1892 1896 1900 1904 1908 1912 1916 1920 1924 1928 1932 1936 1940 1944 1948 1952 1956 1960 1964 1968 1972 1976 1980 1984 1988 1992 1996 2000 2004 2008" = *1900* ]]
then
echo "Found"
fi
if [[ ${leap_yrs[@]} = *1900* ]]
then
echo "Also found"
fi
When you are not sure that your shell supports if [[ ... ]]
, you can use the more portable case construction.
Now that you see how the match is made, you understand that year 19 might be a leap year too. A safer way is to make a string with colons like :1852:1856:...:
and match with *:${year}:*
.
Getting more complex to understand with each improvement? Just make a function isLeapYear (but getting off topic).
EDIT:
The * *
are wildcards (stand for any characters-string). p*m
matches pim, pam, program and pugliam. *8*
matches 4 6 8 10
but does not match 5 7 9
.
In this case you can read it as substring.
I added colons, because 1
is a substring of 1868 1872 1876
, but :1:
is not a substring of :1868:1872:1876: