小编典典

如何在sh中使用'find'的'-prune'选项?

all

我不太明白从给出的例子man find,谁能给我一些例子和解释?我可以在其中结合正则表达式吗?


更详细的问题是这样的:

编写一个 shell 脚本,changeall,它有一个类似的接口changeall [-r|-R] "string1" "string2"。它将查找所有后缀为.h.C.cc或的文件,.cpp并将所有出现的
更改string1string2-r是仅停留在当前目录或包括子目录的选项。

笔记:

  1. 对于非递归的情况,ls是不允许的,我们只能使用findand sed
  2. 我试过find -depth但不支持。这就是为什么我想知道是否-prune可以提供帮助,但不理解来自man find.

EDIT2:我正在做作业,我没有详细询问问题,因为我想自己完成它。既然我已经完成并提交了,现在我可以陈述整个问题。另外,我设法在不使用
的情况下完成了作业-prune,但无论如何我还是想学习它。


阅读 53

收藏
2022-05-18

共1个答案

小编典典

我发现令人困惑-prune的是它是一个动作(比如-print),而不是一个测试(比如-name)。它改变了“待办事项”列表, 但总是返回
true

使用的一般模式-prune是这样的:

find [path] [conditions to prune] -prune -o \
            [your usual conditions] [actions to perform]

您几乎总是希望在-o之后立即使用 (逻辑 OR) -prune,因为测试的第一部分(直到并包括)将为您实际想要的东西-prune返回
false (即:您 不想 修剪的东西)。

这是一个例子:

find . -name .snapshot -prune -o -name '*.foo' -print

这将找到不在“.snapshot”目录下的“*.foo”文件。在这个例子中,-name .snapshot组成[conditions to prune], 并且-name '*.foo' -print[your usual conditions][actions to perform]

重要说明

  1. 如果您只想打印结果,您可能习惯于忽略-print操作。在使用. ___-prune

如果除了(讽刺地)最后没有其他动作,find 的默认行为是用动作“和” 整个 表达式。这意味着写这个:-print``-prune

     find . -name .snapshot -prune -o -name '*.foo'              # DON'T DO THIS

相当于写这个:

     find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS

这意味着它还会打印出您正在修剪的目录的名称,这通常不是您想要的。-print相反,如果这是您想要的,最好明确指定操作:

     find . -name .snapshot -prune -o -name '*.foo' -print       # DO THIS
  1. 如果您的“通常条件”恰好匹配也符合您的修剪条件的文件,则这些文件将 不会 包含在输出中。解决此问题的方法是-type d在修剪条件中添加谓词。

例如, 假设 我们想要删除任何.git以. 你可以试试这个: __.git``.gitignore

    find . -name '.git*' -prune -o -type f -print               # DON'T DO THIS

不会 包含.gitignore在输出中。这是固定版本:

    find . -name '.git*' -type d -prune -o -type f -print       # DO THIS

额外提示:如果您使用的是 GNU 版本find则 texinfo
页面的find
解释比其手册页更详细(大多数
GNU 实用程序都是如此)。

2022-05-18