我的作业要求我创建一个find
版本,可以使用以下参数:
-name
(处理名称的模式)-type
(f和d)-print
-exec
(能够处理{}
,虽然如果exec
存在,您可以假设它始终是最后一个参数,不需要用分号终止它还指出"谓词可以按任何顺序出现,并且隐式短路AND。不要处理-o(OR)。"我也不允许在我的剧本中使用find
。
因此,示例输入将如下所示:
myfind ~/dirtocheck/ -name '*.o' -type f -print -exec /bin/mv {} ~/.TRASH\;
关于如何完成所有这些,我有几个问题。
首先,我想知道如何使用递归来导航路径。这是我的函数的伪代码版本:
recurse_path () {
for i in "$@"; do
# call a function that executes rest of program
if [[ -d "${i}" ]]; then
cd "${i}"
recurse_path $(ls ".")
fi
done
}
其次,我不知道将传递多少参数或者真正如何正确解析它们。在执行任何可以使这更容易的事情之前,我应该做些什么吗?
例如,我假设我们有一个'-exec'
参数,我可以接受任何事情,并将其移动到一个数组中执行。但是我该怎么做呢?
最后,它是什么意思"谓词可以以任何顺序出现,并且隐含地短路并联在一起。"我假设这意味着下一个要执行的每一件事都必须是真的,但我不知道为什么它们会出现故障?
我会很感激任何帮助,甚至是如何构建它以使其发挥作用的想法。
答案 0 :(得分:3)
首先,我想知道如何使用递归来沿着路径导航。
您的代码是一个良好的开端。为了表现得像find
,我会删除对cd
的调用,而是始终使用相对于起始目录的路径。这意味着递归越深,它们就越长。
同样recurse_path $(ls ".")
是一种编写recurse_path *
的复杂方式。
其次,我不知道将传递多少个参数或者真正如何正确解析它们。
作为提示,您可以编写一个循环来检查每次迭代$1
,然后使用shift
在处理完参数后删除它们,以便$1
指向下一组论点。例如,如果$1
为-name
,请在$2
中处理该名称,然后调用shift 2
。
例如,我假设我们有一个'-exec'参数,我可以接受任何过去,并将其移动到一个数组中执行。但是我该怎么做呢?
如果您使用基于shift
的方法,则-exec
的参数自然可以简单地作为"$@"
访问。
最后,它是什么意思“谓词可以以任何顺序出现,并且隐含地短路并联在一起。”我假设这意味着每一件事都必须是真的,以便下一个执行,但我不知道他们为什么会出现故障?
您不能认为-name
出现在-type
之前。它们可能处于任何一种顺序,或者它们可能会丢失,甚至可能重复多次。例如:
myfind ~/dirtocheck/ -name '*.o' -type f
myfind ~/dirtocheck/ -type f -name '*.o'
myfind ~/dirtocheck/ -name 'MyClass*' -name '*.java'
答案 1 :(得分:1)
首先:你的递归看起来很好。我唯一需要注意的是ls
确实不应该以这种方式使用,因为格式化输出。您需要直接使用shell-glob扩展:recurse_path *
。 (请注意,再见默认情况下,这不会包含以.
开头的任何内容。您的作业是否解决了如何处理“隐藏”文件的问题?我认为,find
正常对待它们,这意味着您可能需要打开Bash的dotglob
选项。
(另请注意,JohnKugelman的回答提出了关于完整路径的一个好处。尽管使用cd
仍然可以工作 - 例如,你可以在变量中维护相对路径。虽然没有真正的原因使用cd
。)
第二:你几乎肯定会使用shift
来获取你的论点。请注意,这会更改您的位置参数变量($1
,$2
等)以及列表变量($*
和$@
)。因此,举例来说,如果您注意到$1
(在shift
s之后)为-exec
,那么您可以再次shift
,$@
将包含要执行的命令(modulo替换{}
等)。
第三:是的,短路and
意味着如果不满足条件,则不评估/测试下一个条件;您可能会发现阅读有关短路操作符很有帮助,但这个概念很简单,听起来您可能已经理解了它。我相信“任何订单”条款意味着您可以-type
来-name
之前。{/ p>