Can grep show only words that match search pattern?

前端 未结 14 1642
忘掉有多难
忘掉有多难 2020-11-22 14:35

Is there a way to make grep output \"words\" from files that match the search expression?

If I want to find all the instances of, say, \"th\" in a number of files, I

相关标签:
14条回答
  • 2020-11-22 15:30

    Cross distribution safe answer (including windows minGW?)

    grep -h "[[:alpha:]]*th[[:alpha:]]*" 'filename' | tr ' ' '\n' | grep -h "[[:alpha:]]*th[[:alpha:]]*"
    

    If you're using older versions of grep (like 2.4.2) which do not include the -o option, then use the above. Else use the simpler to maintain version below.

    Linux cross distribution safe answer

    grep -oh "[[:alpha:]]*th[[:alpha:]]*" 'filename'
    

    To summarize: -oh outputs the regular expression matches to the file content (and not its filename), just like how you would expect a regular expression to work in vim/etc... What word or regular expression you would be searching for then, is up to you! As long as you remain with POSIX and not perl syntax (refer below)

    More from the manual for grep

    -o      Print each match, but only the match, not the entire line.
    -h      Never print filename headers (i.e. filenames) with output lines.
    -w      The expression is searched for as a word (as if surrounded by
             `[[:<:]]' and `[[:>:]]';
    

    The reason why the original answer does not work for everyone

    The usage of \w varies from platform to platform, as it's an extended "perl" syntax. As such, those grep installations that are limited to work with POSIX character classes use [[:alpha:]] and not its perl equivalent of \w. See the Wikipedia page on regular expression for more

    Ultimately, the POSIX answer above will be a lot more reliable regardless of platform (being the original) for grep

    As for support of grep without -o option, the first grep outputs the relevant lines, the tr splits the spaces to new lines, the final grep filters only for the respective lines.

    (PS: I know most platforms by now would have been patched for \w.... but there are always those that lag behind)

    Credit for the "-o" workaround from @AdamRosenfield answer

    0 讨论(0)
  • 2020-11-22 15:30

    You could pipe your grep output into Perl like this:

    grep "th" * | perl -n -e'while(/(\w*th\w*)/g) {print "$1\n"}'
    
    0 讨论(0)
提交回复
热议问题