Use*_*123 5 ksh hp-ux quoting timestamps
我正在尝试在 HP-UX Unix 中使用以下命令获取当前日期的文件:
$ ls -lrt ABC.LOG* |grep "`date +"%b %d"`"
Run Code Online (Sandbox Code Playgroud)
但是,它给了我错误:
ksh: : cannot execute
grep: can't open %d
Run Code Online (Sandbox Code Playgroud)
有什么建议?
该错误源于对 的参数的引用grep
以及反引号不能很好地嵌套的事实:
grep "`date +"%b %d"`"
Run Code Online (Sandbox Code Playgroud)
这最好写成
grep "`date +'%b %d'`"
Run Code Online (Sandbox Code Playgroud)
……甚至更好,
grep "$(date +'%b %d')"
Run Code Online (Sandbox Code Playgroud)
事实上,使用$(...)
而不是反引号,您应该能够保留内部双引号:
grep "$(date +"%b %d")"
Run Code Online (Sandbox Code Playgroud)
grepping 输出的另一种方法ls
是做
find . -type f -name "ABC.LOG*" -ctime -1
Run Code Online (Sandbox Code Playgroud)
这将-type f
在当前目录中查找名称与给定模式匹配且 ctime自当前时间起小于 24 小时的所有常规文件 ( ) 。文件的 ctime 是最后一次修改文件数据或元数据的时间。
但这并不完全等同于您想要实现的目标。这也会递归到子目录中。
在 Korn shell 中,就像在 Bourne shell 中一样,引号和反引号(命令替换的古老形式)可能是无与伦比的,您必须帮助标记生成器分辨反引号在哪里结束。在反斜杠内部还有另一个级别的反斜杠处理。
echo "`date"
Run Code Online (Sandbox Code Playgroud)
有效并且与以下相同:
echo "`date`"
echo "$(date)"
Run Code Online (Sandbox Code Playgroud)
和:
echo `echo "foo`
Run Code Online (Sandbox Code Playgroud)
有效并且与以下相同:
echo `echo "foo"`
echo $(echo "foo")
Run Code Online (Sandbox Code Playgroud)
如果你这样做:
grep "`date +"%b %d"`"
Run Code Online (Sandbox Code Playgroud)
这作为一个的grep
单词,然后"`date +"
(双引号内未关闭反引号)串联起来%b
,然后%d
用双引号内的另一个未闭合的反引号连接起来:"`"
。所以就像
grep "$(date +)"%b %d"$()"
Run Code Online (Sandbox Code Playgroud)
(除了出于某种原因,虽然echo "``"
或echo "$()"
不会导致错误,在 中echo "`"
,shell 将尝试执行具有空名称的命令(就像您编写的一样echo "$("")"
)。
所以在这里,你需要使用反斜杠来帮助解析器:
grep "`date +\"%b %d\"`"
Run Code Online (Sandbox Code Playgroud)
这些反斜杠实际上已被删除。它是date +"%b %d"
由命令替换中的子shell 评估的。
在这里,由于ksh
接受未封闭的引号,您实际上也可以这样做:
grep "`date +\"%b %d"
Run Code Online (Sandbox Code Playgroud)
(不是我会建议这样做)。
这也是您如何获得嵌套反引号的方法,如下所示:
echo "`echo \"\`echo \\\"a b\\\"\`\"`"
Run Code Online (Sandbox Code Playgroud)
一个很好的例子,为什么几乎没有人使用这种语法并使用$(...)
较新的形式(ksh
在 80 年代初引入):
echo "$(echo "$(echo "a b")")"
Run Code Online (Sandbox Code Playgroud)
现在,对于您的特定问题,您似乎想要列出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
Run Code Online (Sandbox Code Playgroud)