find 在一个命令中组合多个名称和路径

find 在一个命令中组合多个名称和路径

我有一组相当复杂的文件需要查找和反应(例如复制到文本文件的路径):

例如:

 find / \( -iname "*ssh*" -or -iname "*scp*" \) \( -not -path -"/run" -not -path "/rw/*" -and -not -path "/home/*" -and -not -path "*/qml/*" \) >> ~/files.txt

在这里我想找到与“ssh”和“scp”相关但不在 /run 或 /rw 目录中的所有文件或文件夹。

我将为此添加更多条件,但命令太长了。我怎样才能用正则表达式做到这一点?

答案1

最好是根本不要下降到您想要排除的那些目录中,而不是在事后使用以下命令过滤掉其中的文件! -path <pattern>

LC_ALL=C find / \
       '(' \
          -path /run -o  -path /rw -o -path /home -o -path '*/qml' \
       ')' -prune -o '(' \
          -name '*[sS][hH][hH]*' -o -name '*[sS][cC][pP]*' \
       ')' -print

这里使用POSIXfind语法。对于 GNU find,这可能是:

LC_ALL=C find / -regextype posix-extended \
  -regex '/home|/rw|.*/qml' -prune -o \
  -iregex '.*s(cp|sh)[^/]*' -print

使用 BSD find,您只需使用-E类似 ingrepsed即可获取 POSIX ERE:

LC_ALL=C find -E / \
  -regex '/home|/rw|.*/qml' -prune -o \
  -iregex '.*s(cp|sh)[^/]*' -print

答案2

这是一个带有换行符的版本,更容易阅读,并且修复了一些拼写错误。我假设 GNU 查找,但稍作修改也适用于大多数 BSD 查找。

find / \
     \( -iname "*ssh*" -or -iname "*scp*" \) \
     \( -not -path "/run/*" \
        -not -path "/rw/*" \
        -not -path "/home/*" \
        -not -path "*/qml/*" \) \
     >> ~/files.txt

现在为了简化一点,-iname "*ssh*" -or -iname "*scp*"可以写成正则表达式,例如

find ... \
     -regextype posix-extended \
     -iregex '.*(ssh|scp)[^/]*' \
     ...

现在您可以更轻松地添加额外的名称,例如(ssh|scp|rsync|...).

这些-not -path测试可以组合成一个正则表达式,如下所示:

find ... \
     -not -regex '(/run|/rw|/home|.*/qml)/.*'

find仍然会浪费大量时间探索这些目录,除非您使用-prune

find / \
     -regextype posix-extended \
     -not \( -regex '(/run|/rw|/home|.*/qml)/.*' -prune \) \
     -iregex '.*(ssh|scp)[^/]*' \
     >> ~/files.txt

相关内容