How do I find files that do not contain a given string pattern?

后端 未结 16 1142
半阙折子戏
半阙折子戏 2020-11-28 17:42

How do I find out the files in the current directory which do not contain the word foo (using grep)?

相关标签:
16条回答
  • 2020-11-28 17:48

    The following command excludes the need for the find to filter out the svn folders by using a second grep.

    grep -rL "foo" ./* | grep -v "\.svn"
    
    0 讨论(0)
  • 2020-11-28 17:48

    My grep does not have any -L option. I do find workaround to achieve this.

    The ideas are :

    1. to dump all the file name containing the deserved string to a txt1.txt.
    2. dump all the file name in the directory to a txt2.txt.
    3. make the difference between the 2 dump file with diff command.

      grep 'foo' *.log | cut -c1-14 | uniq > txt1.txt
      grep * *.log | cut -c1-14 | uniq > txt2.txt
      diff txt1.txt txt2.txt | grep ">"
      
    0 讨论(0)
  • 2020-11-28 17:52

    Take a look at ack. It does the .svn exclusion for you automatically, gives you Perl regular expressions, and is a simple download of a single Perl program.

    The equivalent of what you're looking for should be, in ack:

    ack -L foo
    
    0 讨论(0)
  • 2020-11-28 17:52

    Open bug report

    As commented by @tukan, there is an open bug report for Ag regarding the -L/--files-without-matches flag:

    • ggreer/the_silver_searcher: #238 - --files-without-matches does not work properly

    As there is little progress to the bug report, the -L option mentioned below should not be relied on, not as long as the bug has not been resolved. Use different approaches presented in this thread instead. Citing a comment for the bug report [emphasis mine]:

    Any updates on this? -L completely ignores matches on the first line of the file. Seems like if this isn't going to be fixed soon, the flag should be removed entirely, as it effectively does not work as advertised at all.


    The Silver Searcher - Ag (intended function - see bug report)

    As a powerful alternative to grep, you could use the The Silver Searcher - Ag:

    A code searching tool similar to ack, with a focus on speed.

    Looking at man ag, we find the -L or --files-without-matches option:

    ...
    
    OPTIONS
        ...
    
        -L --files-without-matches
               Only print the names of files that don´t contain matches.
    

    I.e., to recursively search for files that do not match foo, from current directory:

    ag -L foo
    

    To only search current directory for files that do not match foo, simply specify --depth=0 for the recursion:

    ag -L foo --depth 0
    
    0 讨论(0)
  • 2020-11-28 17:54

    Problem

    I need to refactor a large project which uses .phtml files to write out HTML using inline PHP code. I want to use Mustache templates instead. I want to find any .phtml giles which do not contain the string new Mustache as these still need to be rewritten.

    Solution

    find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'

    Explanation

    Before the pipes:

    Find

    find . Find files recursively, starting in this directory

    -iname '*.phtml' Filename must contain .phtml (the i makes it case-insensitive)

    -exec 'grep -H -E -o -c 'new Mustache' {}' Run the grep command on each of the matched paths

    Grep

    -H Always print filename headers with output lines.

    -E Interpret pattern as an extended regular expression (i.e. force grep to behave as egrep).

    -o Prints only the matching part of the lines.

    -c Only a count of selected lines is written to standard output.


    This will give me a list of all file paths ending in .phtml, with a count of the number of times the string new Mustache occurs in each of them.

    $> find . -iname '*.phtml$' -exec 'grep -H -E -o -c 'new Mustache' {}'\;
    
    ./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
    ./app/MyApp/Customer/View/Account/studio.phtml:0
    ./app/MyApp/Customer/View/Account/orders.phtml:1
    ./app/MyApp/Customer/View/Account/banking.phtml:1
    ./app/MyApp/Customer/View/Account/applycomplete.phtml:1
    ./app/MyApp/Customer/View/Account/catalogue.phtml:1
    ./app/MyApp/Customer/View/Account/classadd.phtml:0
    ./app/MyApp/Customer/View/Account/orders-trade.phtml:0
    

    The first pipe grep :0$ filters this list to only include lines ending in :0:

    $> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$
    
    ./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
    ./app/MyApp/Customer/View/Account/studio.phtml:0
    ./app/MyApp/Customer/View/Account/classadd.phtml:0
    ./app/MyApp/Customer/View/Account/orders-trade.phtml:0
    

    The second pipe sed 's/..$//' strips off the final two characters of each line, leaving just the file paths.

    $> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
    
    ./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml
    ./app/MyApp/Customer/View/Account/studio.phtml
    ./app/MyApp/Customer/View/Account/classadd.phtml
    ./app/MyApp/Customer/View/Account/orders-trade.phtml
    
    0 讨论(0)
  • 2020-11-28 17:56

    The following command could help you to filter the lines which include the substring "foo".

    cat file | grep -v "foo"
    
    0 讨论(0)
提交回复
热议问题