I am trying to obtain the full date (created or modified) of a particular file for passing to another program. I have tried variations of options with the ls command but none provide a full date for files less than 6 months old and I have limit usage of the options. When I try certain options I have seen trying to research this I get the following message:
usage: ls [-1ACFHLNRabcdefgilmnopqrstuxEUX] [File...]
None of which seems to provide what I needs as far as I can tell so I tried to use the stat command but it is not available to me.
I am using the Korn shell on AIX 5.3 which has limited commands available, can anyone suggest another way that I might be able to obtain a file’s created or modified date as a full date (either dd/mm/yyyy or yyyy/mm/dd).
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
With ls, though you may not always be able to get the time, you should be able to derive the date (year, month and day of the month).
In the C locale, the date output in ls -l should either be Mmm dd HH:MM for recent files (and you should be able to derive the year (either this year or the previous one) or Mmm dd YYYY for older files or files with a modification time in the future. So you should always be able to get the date (YYYY-mm-dd) out of that:
eval "$(date +'year=%Y month=%m')"
LC_ALL=C ls -dn file | awk -v y="$year" -v m="$month" '{
month = index("--JanFebMarAprMayJunJulAugSepOctNovDec", $6) / 3
day = $7
if ($8 ~ /:/)
year = y - (month > m)
else
year = $8
printf "%04d-%02d-%02dn", year, month, day
exit}'
Now, if you want the full modification time with maximum precision, I’m afraid there is no standard command for that.
You’ll find some ls implementations that have options for that (ls --full-time with GNU ls or -D <format> with FreeBSD ls for instance)
There exist a number of different and incompatible implementations of a stat command (IRIX, zsh builtin, GNU, BSD) that can give you that.
Or you could use the -printf predicate of GNU find. Or the -r option of GNU date.
Not all implementations will give you sub-second granularity. And beware of time zones and DST as depending on the format you choose and the timezone you’re in, a given output may be ambiguous and refer to more than one possible date.
For symlinks, you may also want to ask yourself whether it’s the modification time of the link or its target you’re after. Some of the options mentioned here will do one or the other by default and some of them can be told to do one or the other on demand.
zshstat:stat -F '%Y-%m-%d %T.%N %z' +mtime file
↳1992-05-13 14:57:00.123368710 +0100- GNU
stat:stat -c %y file
↳1992-05-13 14:57:00.123368710 +0100 - BSD
stat:stat -t '%F %T %z' -f %Sm file
↳1992-05-13 14:57:00 +0100 - IRIX
stat:stat -m file - GNU
find:find file -prune -printf '%TF %TT %Tzn'
↳1992-05-13 14:57:00.1233687100 +0100 - GNU
date:date -r file '+%F %T.%N %z'
↳1992-05-13 14:57:00.123368710 +0100 - FreeBSD
ls:ls -D '[%F %T %z]' -l file
↳-r-xr-xr-x 2 bin bin 372298 [1992-05-13 14:57:00 +0100] file - GNU
ls:ls --full-time -l file
↳-r-xr-xr-x 2 bin bin 372298 1992-05-13 14:57:00.123368710 +0100 file - ast-open
ls:ls -Z '%(mtime:time=%F %T.%N %z)s'
↳1992-05-13 14:57:00.123368710 +0100
AIX, which your ls synopsis suggests you may be using has an istat command (AIX 5.3 man page) that displays dates in full (without sub-second granularity, and ambiguous unless you force TZ to UTC0), though not that easy to parse:
$ LC_ALL=C TZ=UTC0 istat file Inode 10360 on device 10/6 File Protection: r-xr-xr-x Owner: 2(bin) Group: 2(bin) Link count: 2 Length 372298 bytes Last updated: Wed May 13 14:08:13 1992 Last modified: Wed May 13 13:57:00 1992 Last accessed: Sun Jan 31 15:49:23 1993
Also note that for symlinks, you’ll get the date of the target of the symlink, not the symlink itself.
If you don’t have access to any of those, your best bet for portability may be perl:
$ perl -MPOSIX -le 'print strftime("%Y-%m-%d %T %z", localtime((lstat(shift))[9]))' file
1992-05-13 14:57:00 +0100
Note that few systems have a creation time for files (sometimes called birth time), and there’s no standard API, let alone command to query it, so the situation is even worse than for the modification time.
Method 2
If you have GNU ls:
ls --time-style=long-iso -l
or
ls --time-style=+FMT -l
where FMT follows date command format. In your case:
ls --time-style=+%Y/%m/%d -l
Method 3
Here is a POSIX function to do that:
mtime() {
touch -r "$1" /etc/fstab
diff -u /etc/fstab /dev/null | head -n 1 | cut -f 2
}
Result:
$ mtime ~/.profile
2019-07-01 06:25:34.000000000 -0500
http://cup.github.io/autumn/util/path/file-mtime
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0