BASH doesn't like my regex
First, the quotes suppress the meaning of the special characters in the regex (online manual):
An additional binary operator,
=~
, is available, ... Any part of the pattern may be quoted to force the quoted portion to be matched as a string. ... If you want to match a character that’s special to the regular expression grammar, it has to be quoted to remove its special meaning.
The manual goes on to recommend putting the regex in a variable to prevent some clashes between the shell parsing and the regex syntax.
Second, \d
doesn't do what you think it does, but just matches a literal d
.
Also note that ${BASH_REMATCH[0]}
contains the whole matching string, and indexes 1
and up contain the captured groups.
I'd also strongly suggest using four-digit years, so:
modified=$(stat -c %y "$file")
re='^([0-9]{4})-([0-9]{2})'
if [[ $modified =~ $re ]]; then
echo "year: ${BASH_REMATCH[1]}"
echo "month: ${BASH_REMATCH[2]}"
else
echo "invalid timestamp"
fi
For a file modified today, that gives year: 2018
and month: 08
. Note that numbers with a leading zero will be considered octal by the shell and possibly other utilities.
(Four-digit years have less issues if you ever need to handles dates from the 1900's, and they're easier to recognize as years and not days of month.)
Don't need regular expressions for this:
$ touch -t 197001010000 myfile
$ ls -l myfile
-rw-rw-r-- 1 jackman jackman 0 Jan 1 1970 myfile
$ IFS='-' read -r year month _rest < <(stat -c %y myfile)
$ echo "$year:${year#??}"$month"
1970:70:01
As an alternative, with GNU date
, you can do:
eval "$(date -r "$file" +'year=%Y month=%-m day=%-d')"
To have the modification time's year, month and day component stored in $year
, $month
and $day
respectively (as decimal integers, remove the -
s in %-m
and %-d
if you care for the leading zeros; see also %y
for 2-digit years).
(note that contrary to GNU stat
, for files of type symlink, the modification time of the target of the symlink is considered rather than that of the symlink itself. With GNU stat
, you'd use stat -L
).