我不太了解man find提供的示例,有人可以给我一些示例和解释吗?我可以在其中结合正则表达式吗?

更详细的问题是这样的:

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

注意:

  • 对于非递归情况,不允许ls,我们只能使用findsed
  • 我尝试了find -depth,但不支持。这就是为什么我想知道-prune是否可以提供帮助,但不理解man find中的示例的原因。


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

    最佳答案

    我对-prune感到困惑的是,它是一个 Action (例如-print),而不是测试(例如-name)。它会更改“待办事项”列表,但始终返回true。
    使用-prune的一般模式是这样的:

    find [path] [conditions to prune] -prune -o \
                [your usual conditions] [actions to perform]
    
    您几乎总是希望在-o之后立即添加-prune(逻辑OR),因为测试的第一部分(直到-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]
    重要说明:
  • 如果您只想打印结果,则可能会习惯于省略-print操作。通常,在使用-prune时,您不想这样做。
    find的默认行为是,如果最后没有-print以外的 Action ,则使用-prune Action “和”整个表达式。这意味着编写此代码:
     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
    
  • 如果您的“正常情况”恰好与也符合修剪条件的文件相匹配,则这些文件将不包含在输出中。解决此问题的方法是在修剪条件中添加-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版本的findthe texinfo page for find 的说明要比其手册页更为详尽(大多数GNU实用程序都是如此)。

    关于regex - 在sh中如何使用 '-prune'的 'find'选项?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1489277/

    10-10 04:12