修剪'选择'找到'sh?

我不太明白从'男人发现'给出的例子,任何人都可以给我一些例子和解释吗? 我可以结合正则表达式吗?


更详细的问题是这样的:编写一个shell脚本changeall,它有一个类似于“changeall [-r | -R]”string1“”string2“的接口,它会查找所有具有.h,.C后缀的文件,.cc或.cpp,并将所有出现的“string1”更改为“string2”。-r仅用于保留当前目录或包含子目录。注意:1)对于非递归情况,不允许使用'ls' ,我们只能使用'find'和'sed'2)我试过'find -depth'但它不被支持,这就是为什么我想知道'-prune'是否可以提供帮助,但是不理解'男人找到'。


编辑2:我在做任务,我没有很好地提问,因为我想自己完成它。 由于我已经完成并交付了,现在我可以陈述整个问题。 另外,我设法在不使用-prune的情况下完成作业,但仍想学习它。


我已经找到混淆约约的事情-prune是它的一个动作(如-print ),不是测试(如-name )。 它改变了“待办事项”列表,但总是返回true。

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

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

你几乎总是希望在-prune之后立即使用-o ,因为测试的第一部分(最多包括-prune )会为你实际需要的东西返回false(即:你不想修剪的东西)。

这是一个例子:

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

这将找到不在“.snapshot”目录下的“* .foo”文件。 在这个例子中, -name .snapshot是“要修剪的东西的测试”,而-name '*.foo' -print -name .snapshot是“通常放在路径后面的东西”。

重要提示

  • 如果你想要做的只是打印你可能会用来排除-print操作的结果。 当使用-prune时,你通常不想这样做。

    find的默认行为是如果在最后没有除-prune之外的行为(具有讽刺意味的),则使用-print操作来“和”整个表达式。 这意味着写这个:

    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东西),但.git ,它想看到所有文件,包括像.gitignore 。 你可以试试这个:

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

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

    find . -type d -name '.git*' -prune -o -type f -print       # DO THIS
    
  • 额外提示:如果您使用的GNU版本find ,对于文本信息文件find具有比其手册页更详细的解释(这是大多数的GNU工具真)。


    请注意--prune不会像有些人所说的那样阻止进入任何目录。 它可以防止降序到符合其应用测试的目录。 也许一些例子会有所帮助(参见底部的正则表达式示例)。 对不起,这太冗长了。

    $ find . -printf "%y %pn"    # print the file type the first time FYI
    d .
    f ./test
    d ./dir1
    d ./dir1/test
    f ./dir1/test/file
    f ./dir1/test/test
    d ./dir1/scripts
    f ./dir1/scripts/myscript.pl
    f ./dir1/scripts/myscript.sh
    f ./dir1/scripts/myscript.py
    d ./dir2
    d ./dir2/test
    f ./dir2/test/file
    f ./dir2/test/myscript.pl
    f ./dir2/test/myscript.sh
    
    $ find . -name test
    ./test
    ./dir1/test
    ./dir1/test/test
    ./dir2/test
    
    $ find . -prune
    .
    
    $ find . -name test -prune
    ./test
    ./dir1/test
    ./dir2/test
    
    $ find . -name test -prune -o -print
    .
    ./dir1
    ./dir1/scripts
    ./dir1/scripts/myscript.pl
    ./dir1/scripts/myscript.sh
    ./dir1/scripts/myscript.py
    ./dir2
    
    $ find . -regex ".*/my.*p.$"
    ./dir1/scripts/myscript.pl
    ./dir1/scripts/myscript.py
    ./dir2/test/myscript.pl
    
    $ find . -name test -prune -regex ".*/my.*p.$"
    (no results)
    
    $ find . -name test -prune -o -regex ".*/my.*p.$"
    ./test
    ./dir1/test
    ./dir1/scripts/myscript.pl
    ./dir1/scripts/myscript.py
    ./dir2/test
    
    $ find . -regex ".*/my.*p.$" -a -not -regex ".*test.*"
    ./dir1/scripts/myscript.pl
    ./dir1/scripts/myscript.py
    
    $ find . -not -regex ".*test.*"                   .
    ./dir1
    ./dir1/scripts
    ./dir1/scripts/myscript.pl
    ./dir1/scripts/myscript.sh
    ./dir1/scripts/myscript.py
    ./dir2
    

    通常情况下,我们在Linux中执行的操作和我们认为的方式是从左到右的。
    所以你会先写下你想要的东西:

    find / -name "*.php"
    

    然后你可能会进入并意识到你从你不想要的目录中获得太多文件。 让我们排除/媒体以避免搜索您安装的驱动器。
    您现在只需将以下命令添加到上一个命令:

    -print -o -path '/media' -prune
    

    所以最终的命令是:

    find / -name "*.php" -print -o -path '/media' -prune
    

    ............... | <---包括---> | .................... | < - --------排除---------> |

    我认为这种结构要容易得多,并且与正确的方法相关

    链接地址: http://www.djcxy.com/p/78133.html

    上一篇: prune' option of 'find' in sh?

    下一篇: How to exclude a hidden folder from being deleted