我的目录中有一堆文件。
# ls -1
file1
file2
file3
file4
file5
file6
file7
file8
file9
file10
任务是查找早于file5
.我可以这样做
# find . ! -newer file5
./file1
./file2
./file3
./file4
./file5
现在我有一个文件,其中对上述任何/所有内容的引用可能类似于
# logfile=log
cat ${logfile}
/var/log/app/file1
/var/log/app/file3
/var/log/app/file5
现在我只想要那些早于 file5 且也在日志文件中的文件的列表。所以结果列表将是:
file1
file3
file5
我尝试像这样从这些文件名中查找文件名,但它不起作用。
find . ! -newer file4 -exec bash -c 'for i in {}; do grep $i ${logfile}; done' \;
答案1
如果目录是/var/log/app
然后而不是find . ! -newer file5
运行find /var/log/app ! -newer /var/log/app/file5
。这样, 的输出find
将采用log
.
find
然后您可以仅使用一个过滤输出grep
:
find /var/log/app ! -newer /var/log/app/file5 | grep -xFf log
-x
导致grep
匹配整行;-F
告诉它将模式视为固定字符串;-f
从指定文件中读取模式。这些选项是可移植的。
或者(或者在当前工作目录不是/var/log/app
,但您想假装它是的情况下)创建第二个日志,因此其中的条目与./…
原始工作目录的一般格式匹配find
:
sed 's|^/var/log/app/|./|' log > log2
新日志包含可用于过滤原始find
命令输出的相对路径:
find . ! -newer file5 | grep -xFf log2
笔记:
! -newer file5
并不意味着“比file5
”更老。此测试匹配file5
任何同样旧的文件。- 附加选项/测试(例如
-maxdepth 1
,-type f
)可能有用。
你的尝试:
find . ! -newer file5 -exec bash -c 'for i in {}; do grep $i ${logfile}; done' \;
在许多方面都有缺陷或次优:
- 您将日志文件视为数据,将路径名视为
find
模式。如上所示,反之亦然更容易。 - 在内部的上下文中
bash
,$i
和${logfile}
不被引用。它们应该用双引号引起来 - 您嵌入
{}
了 shell 代码。一般来说,嵌入的{}
行为就像一个不带引号的变量,但无论你如何引用它,都有命令注入漏洞。所以情况更糟。 - 您使用了
-exec … \;
which 替换了{}
一个路径名(而不是-exec … {} +
),但您仍然写得for i in {}
好像您期望有很多路径名一样。一般来说,内壳可能会将其所代替的内容解释为{}
多个单词。文件名生成也可能被触发。这就是上面提到的“像一个不带引号的变量”行为。因此,一般来说,您可能会得到许多循环的“路径名”,但不是您所期望的。 logfile
不在环境中,因此内壳将扩展$logfile
为空字符串。您不希望外壳扩展它(使其与嵌入有类似的缺陷{}
)。