DEV Community

Michael
Michael

Posted on

find命令,由不能打印‘afile’总结到的

关于

find命令是常用到的,读到manpage里面一段话不是很明白,于是整个manpage读了一遍终于整明白了。

Please note that -a when specified implicitly (for example by two
tests appearing without an explicit operator between them) or
explicitly has higher precedence than -o.  This means that `find .
-name afile -o -name bfile -print` will never print afile.
Enter fullscreen mode Exit fullscreen mode

就是说find . -name afile -o -name bfile -print命令即使afile存在也不会打印出来,这就很奇怪了,读起来是afile或者bfile就print,看起来很直观,但是不是这么判断的,下面我们总结下manpage和常见用法习惯。

用法

find [OPTIONS] [starting-point] [EXPRESSION]
Enter fullscreen mode Exit fullscreen mode
  • OPTIONS 里面 -H -L -P 用于表示如何处理symbolic link; -O 表示优化级别,一般用不到; -D 用于调试,比如
`-D help` 打印出所有调试选项
`-D tree` 打印出predicate list,可以看到默认添加的参数等,非常有用
Enter fullscreen mode Exit fullscreen mode
  • starting-point 可以有多个,最好使用相对路径和绝对路径,比如./abc/abc, 避免被乱解释了,比如路径开头为-,就会被解释为expression argument。
  • EXPREESION 用于表示怎么匹配文件和匹配后怎么做。包括以下几个部分: Tests, Actions, Global options, Positional options, Operators

    1. Tests 返回true或者false。根据文件属性包括日期、权限、状态、大小等,选择我们关心部分作为测试参数,比如-empty表示文件内容为空的判断
    2. Actions 返回true或者false。 匹配文件怎么做,比如,-print将当前匹配文件名打印
    3. Global Options 总是返回true。 影响所有的tests和actions参数,比如, -depth指示find按照深度优先方式traverse
    4. Positional Options 总是返回true。 只是影响他之后的tests和actions参数,比如,-regextype 指示他后面使用的regex方言类型
    5. Operators 逻辑连接参数,如果expr之间没有逻辑连接默认是-a表示and。 而且不管显式或者隐式-a优先级都高于-o,其他有趣的还包括 () 调整precedence ! expr或者(-not expr) 取反 expr1, expr2 2个表达式都会执行,但是结果取expr2的, 举例
     find . ! -path './node_modules/*' \( \( -type f -print \) , \( -type d -exec echo 'directory: {}' \; \) \)     
    

注意点

  1. 默认action是-print, 这里的默认是说,如果命令中没有任何一个action, 会在最后添加-a -print, 但是如果有多个判断分支,但一个有action, 那不会添加默认,比如

     find . -name afile -o -name bfile -print
    

    这个afile判断是不会添加-print的,由于-a优先级高于-o, 所以最后变成了

     find . ( -name afile ) -o ( -name bfile -a -print )
    

    其中默认添加了-a, 遇到afile时候就会跳过了,相当于continue, 可以使用-D tree看到最后执行的命令表达式
    find -D tree . -name afile -o -name bfile -print会得到:

     Optimized Command Line:
          -name afile [est success rate 0.1] -o [est success rate 0.2]  ( -name bfile [est success rate 0.1] -a [est success rate 0.1] -print [est success rate 1]  )
    
  2. 如果只有-prune或者-quit,还是会添加默认-print

    -prune表示如果是文件夹,不递归他。-prune总是返回true, 常用于跳过某个文件或者目录,比如find . -path './node_modules' -prune -o -type f -print;

    -quit用于成功了整个命令退出,比如打印第一个匹配成功的文件 find . -path './node_moduels' -prune -o -type f -print -quit

  3. 以下actions会禁止-print, 包括-delete, -exec, -execdir, -ok, -okdir, -fls, -fprint, -fprintf, -ls, -print, -printf

  4. -maxdepth 0 (global options)可以指示只处理start point

  5. 为了防止被当成SHELL中特殊字符,find命令中参数有些要注意转译,比如括号、分号、加号等,凡是在SHELL中特殊字符尽量转移,不然后果未知, 比如find . -path './node_modules' -prune -o -type f -exec echo {} ;如果最后的;不转译,find命令找不到结束符号报错。还有最后的+也是一样, find . -path './node_modules' -prune -o -type f -ok echo {} \;, -ok每次执行命令都会询问。

  6. -exec COMMAND [\;|\+]
    最后;+, 前者是每次都执行一次COMMAND, 后者是将参数以空格形式分割,最后执行一次COMMAND。

  7. -name pattern
    表示file的basename是否符合pattern, 比较时候会去掉leading directory

  8. -path pattern
    匹配的是整个filename, 包括路径, 比如

     find . \( ! -path './node_modules/*' ! -name 'eslint.config.js' -type f \) -print
    
  9. -print0

    主要是防止文件名含有特殊字符,比如\n, space等,批处理时会被转译截断,所以使用\0结尾,跟xargs -0配对使用

答案

-a优先级比-o高,另外-name afile不会添加-print, 所以即使匹配到了还是会无声的过了,最后只是打印了bfile, 如果存在的话。

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

Image of AssemblyAI

Automatic Speech Recognition with AssemblyAI

Experience near-human accuracy, low-latency performance, and advanced Speech AI capabilities with AssemblyAI's Speech-to-Text API. Sign up today and get $50 in API credit. No credit card required.

Try the API

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay