csh
在我的 SunOS 系统上,我尝试使用、ls
和查找晚上 7 点之后创建的所有文件awk
。
ls -l "${Source_files_Dir}"/*.zip| awk -v today="$(date "+%b %d")" '{
date=$6" "$7; time=$8; if (date == today && substr(time,1,2) >= 19)
print $9 }'|xargs -n 1 basename
该命令在 中有效ksh
,但在csh
.我怎样才能实现这一目标csh
?
注意: SunOS 上-newermt
不支持该选项find
,因此我尝试使用上面的ls
命令。
答案1
无论如何,这种方法非常不稳定,你最好使用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
不知道为什么你会在本世纪使用 csh,但请注意,csh
如果$Source_files_Dir
包含换行符,上述内容将无法正常工作。在 csh 中替换"$Source_files"
为$Source_files:q
会更好(但在其他 shell 中不再起作用)。
Solaris(以前称为 SunOS)通常也会zsh
安装,只需执行以下操作:
autoload age
print -rC1 -- $Source_files_Dir/*.zip(Ne[age 19:00]:t)
列出您的方法存在的一些问题:
ls -l "${Source_files_Dir}"/*.zip
: 如果$Source_files_Dir
以 开头-
,它将被 视为一个选项ls
。一般来说,如果后面的内容是可变的,则需要--
标记选项的结尾。- 如果任何 zip 文件属于目录类型,则将列出其内容。当
ls
与 glob 或一般可变数据一起使用时,您通常需要使用以下-d
选项:ls -ld -- ...
- 具体来说,在 csh 中,如果
$Source_files_Dir
包含换行符,将导致语法错误。$Source_files_Dir:q
如上所述,在 csh 中更好。 - 在任何情况下,您都假设文件路径(
ls -l
也报告的文件名和符号链接目标)在处理ls
基于行的输出时不包含换行符。 - 您假设日期/时间位于字段 6、7、8 中,如果用户名或组名包含空格,这些字段将会崩溃。使用
-n
代替(或补充)-l
来获取数字 uid/gids 会使其更加健壮(并避免可能昂贵的名称转换)。 date +%d
输出一个用 0 填充的数字,而对于许多ls
实现和许多语言环境(这是 C/POSIX 语言环境中的 POSIX 要求),ls -l
输出一个用空格填充的数字 (date +%e
)。ls -l
最近日期的输出Mon dd HH:MM
不是将来的日期,而是Mon dd YYYY
您的方法无法处理的其他日期的输出。- 如果没有该
-L
选项,对于符号链接,它是符号链接的修改时间,而不是它指向的将列出的 zip 文件的修改时间。perl
或stat()
与目标的实时时间一起使用zsh
。age
- 对于您的
{print $9}
,除了用户/组名称不包含空格之外,您还假设文件路径也不包含空格。 xargs
如果文件路径包含反斜杠或引号,并且不在 C 语言环境中运行它,则对未在语言环境编码中进行文本编码的文件名上使用该原始输出将会失败。- 如果目录中没有未隐藏的 zip 文件,在 csh 中,您将收到错误
No match
并且ls
不会运行(这至少比ls
使用字面模式调用的 Bourne 风格行为更好),但xargs
仍然会运行,并且basename
仍然会在没有参数的情况下运行一次,可能会导致令人困惑的错误。
答案2
我得到了 csh 的答案,而不是'$'
使用backticks
将今天的日期存储到变量中,today
而是将其放入awk
.
set today=`date "+%b %d"`
ls -l "$Source_files_Dir"/*.zip | awk -v today="$today" ' \
{ \
date=$6" "$7; \
time=$8; \
if (date == today && substr(time,1,2) >= 19) print $9; \
}'|xargs -n 1 basename