我试图在 HP-UX Unix 中使用以下命令获取当前日期的文件:
$ ls -lrt ABC.LOG* |grep "`date +"%b %d"`"
但是,它给了我错误:
ksh: : cannot execute
grep: can't open %d
有什么建议么?
答案1
该错误源于对参数的引用grep
以及反引号不能很好地进行嵌套这一事实:
grep "`date +"%b %d"`"
这更好地写成
grep "`date +'%b %d'`"
...或者甚至更好,
grep "$(date +'%b %d')"
事实上,$(...)
您应该能够保留内部双引号,而不是反引号:
grep "$(date +"%b %d")"
grep 输出的另一种选择ls
是
find . -type f -name "ABC.LOG*" -ctime -1
这将找到-type f
当前目录中名称与给定模式匹配且 ctime 为的所有常规文件 ( )自当前时间起不到 24 小时。文件的 ctime 是最后一次修改文件数据或元数据的时间。
但这并不完全等同于您想要实现的目标。这也会递归到子目录中。
答案2
在 Korn shell 中,就像在 Bourne shell 中一样,引号和反引号(命令替换的古老形式)可能是不匹配的,您必须帮助标记器来判断反引号在哪里结束。反引号内部还有另一级反斜杠处理。
echo "`date"
有效并且与以下相同:
echo "`date`"
echo "$(date)"
和:
echo `echo "foo`
有效并且与以下相同:
echo `echo "foo"`
echo $(echo "foo")
如果你这样做:
grep "`date +"%b %d"`"
这被视为一个grep
单词,然后("`date +"
双引号内未闭合的反引号)与双引号内的另一个未闭合反引号: 连接。所以就像%b
%d
"`"
grep "$(date +)"%b %d"$()"
(除了由于某种原因,虽然echo "``"
或echo "$()"
不会导致错误,但在 中echo "`"
,shell 将尝试执行具有空名称的命令(就像您编写了echo "$("")"
)。
所以在这里,你需要使用反斜杠来帮助解析器:
grep "`date +\"%b %d\"`"
这些反斜杠实际上已被删除。它是date +"%b %d"
由命令替换中的子 shell 进行评估的。
在这里,由于ksh
接受未闭合的引号,您实际上也可以这样做:
grep "`date +\"%b %d"
(并不是说我建议这样做)。
这也是获得嵌套反引号的方法,如下所示:
echo "`echo \"\`echo \\\"a b\\\"\`\"`"
一个很好的例子,为什么很少有人使用该语法并使用较新的形式(在 80 年代初$(...)
引入):ksh
echo "$(echo "$(echo "a b")")"
现在,对于您的特定问题,您似乎想要列出ABC.LOG*
当前目录中今天最后修改的文件。为此,你可以这样做:
touch -t "$(date +%Y%m%d0000)" .start-of-day &&
find . ! -name . -prune -name 'ABC.LOG.*' \
-newer .start-of-day -type f -exec ls -lrtd {} + &&
rm -f .start-of-day
答案3
该find
命令可用于正确的工具,而不是 dols
和grep
ing 结果,因此请注意不解析ls
结果。
find /path/to/ -type f -name "ABC.LOG*$(date +"%b %d")*"
上面是查找今天的日期文件名,如果您正在查找今天创建/修改的文件,您可以find
这样使用(GNU 版本find
):
find /path/to -type f -name "ABC.LOG*" -newermt 00:00
或者在过去 24 小时内:
find /path/to -type f -name "ABC.LOG*" -newermt yesterday
或者如下:
find /path/to -type f -name "ABC.LOG*" -newermt "$(date +"%b %d")"