That approach is quite flaky anyway, you would be better of using perl
:
perl -MPOSIX -MFile::Basename -le '@start = localtime; @start[0..2] = (0,0,19); $start = mktime(@start); for (@ARGV) {print basename$_ if @s = stat$_ and $s[9] >= $start}' -- "$Source_files_Dir"/*.zip
Not sure why you'd be using csh in this century, but note that the above doesn't work properly in csh
if $Source_files_Dir
contains newline characters. Replacing "$Source_files"
with $Source_files:q
would be better in csh (but not work any longer in other shells).
Solaris (formerly known as SunOS) would also usually have zsh
installed, where it's just a matter of doing:
autoload age
print -rC1 -- $Source_files_Dir/*.zip(Ne[age 19:00]:t)
Listing some of the problems with your approach:
ls -l "${Source_files_Dir}"/*.zip
: if $Source_files_Dir
starts with -
, it will be treated as an option by ls
. Generally, you need --
to mark the end of options if what follows is variable.
- if any of the zip files are of type directory, its their contents that will be listed. When using
ls
with a glob or generally variable data, you generally want to use the -d
option: ls -ld -- ...
- In csh specifically, if
$Source_files_Dir
contains newline characters, that will cause a syntax error. $Source_files_Dir:q
is better in csh as noted above.
- In any case, you're assuming the file paths (file names and symlink targets which
ls -l
also reports) don't contain newline characters as you're processing the output of ls
line based.
- You're assuming the date/time is in fields 6, 7, 8 which will fall apart if user or group names contain whitespace. Using
-n
instead of (or in addition to) -l
to get numeric uid/gids would make it more robust (and avoid the potentially costly translation to names).
date +%d
outputs a 0-padded number, while with many ls
implementations and in many locales (and that's a POSIX requirement in the C/POSIX locale), ls -l
outputs a space-padded number (date +%e
).
ls -l
outputs Mon dd HH:MM
for recent dates not in the future, but Mon dd YYYY
for others which your approach doesn't handle.
- without the
-L
option, for symlinks, it's the modification time of the symlink as opposed to that of the zip file it points to that will be listed. perl
's stat()
or zsh
's age
work with the mtime of the target.
- with your
{print $9}
, in addition to user/group names not containing whitespace, you're assuming the file paths don't either.
- using
xargs
on that raw output will fail if file paths contain backslashes or quotes, and by not running it in the C locale, on file names that are not text encoded in the locale's encoding.
- if there's no unhidden zip file in the directory, in csh, you'll get a
No match
error and ls
won't be run (which at least is better than the Bourne-style behaviour where ls
is called with the pattern literally), but xargs
will still be run, and basename
will still be run once with no argument likely causing a confusing error.
ksh
, then why not useksh
? What errors do you get fromcsh
? What Unix are you on? What implementation offind
do you have access to?/bin/sh
is even ksh93 which has date manipulation built in.ls
and don't write scripts withcsh
. Also make sure if you're on Solaris that you use /usr/xpg[4 or 6]/bin/awk
ornawk
, not /usr/bin/awk.