How can I get `find` to ignore .svn directories?

后端 未结 20 1434
迷失自我
迷失自我 2020-12-04 05:05

I often use the find command to search through source code, delete files, whatever. Annoyingly, because Subversion stores duplicates of each file in its .

相关标签:
20条回答
  • 2020-12-04 05:46

    why not just

    find . -not -iwholename '*.svn*'
    

    The -not predicate negates everything that has .svn anywhere in the path.

    So in your case it would be

    find -not -iwholename '*.svn*' -name 'messages.*' -exec grep -Iw uint {} + \;
    
    0 讨论(0)
  • 2020-12-04 05:48

    GNU find

    find .  ! -regex ".*[/]\.svn[/]?.*"
    
    0 讨论(0)
  • 2020-12-04 05:48

    i usually pipe the output through grep one more time removing .svn, in my use it isn't much slower. typical example:

    find -name 'messages.*' -exec grep -Iw uint {} + | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'
    

    OR

    find . -type f -print0 | xargs -0 egrep messages. | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'
    
    0 讨论(0)
  • 2020-12-04 05:49

    Note that if you do

    find . -type f -name 'messages.*'

    then -print is implied when the whole expression (-type f -name 'messages.*') is true, because there is no 'action' (like -exec).

    While, to stop descending into certain directories, you should use anything that matches those directories and follow it by -prune (which is intended to stop descending into directories); like so:

    find . -type d -name '.svn' -prune

    This evaluates to True for the .svn directories, and we can use boolean short-circuit by following this by -o (OR), after which what follows after the -o is only checked when the first part is False, hence is not a .svn directory. In other words, the following:

    find . -type d -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}

    will only evalute what is right of the -o, namely -name 'message.*' -exec grep -Iw uint {}, for files NOT inside .svn directories.

    Note that because .svn is likely always a directory (and not for example a file), and in this case certainly isn't matching the name 'message.*', you might as well leave out the -type d and do:

    find . -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}

    Finally, note that if you omit any action (-exec is an action), say like so:

    find . -name '.svn' -prune -o -name 'message.*'

    then the -print action is implied but will apply to the WHOLE expression, including the -name '.svn' -prune -o part and thus print all .svn directories as well as the 'message.*' files, which is probably not what you want. Therefore you always should use an 'action' in the right-hand side of the boolean expression when using -prune in this way. And when that action is printing you have to explicitly add it, like so:

    find . -name '.svn' -prune -o -name 'message.*' -print

    0 讨论(0)
  • 2020-12-04 05:49

    Try findrepo which is a simple wrapper around find/grep and much faster than ack You would use it in this case like:

    findrepo uint 'messages.*'
    
    0 讨论(0)
  • 2020-12-04 05:51

    To ignore .svn, .git and other hidden directories (starting with a dot), try:

    find . -type f -not -path '*/\.*'
    

    However, if the purpose of using find is searching within the files, you may try to use these commands:

    • git grep - specially designed command for searching patterns within the Git repository.
    • ripgrep - which by default ignores hidden files and files specified in .gitignore.

    Related: How do I find all files containing specific text on Linux?

    0 讨论(0)
提交回复
热议问题