[HN Gopher] Grep flags - the good stuff
       ___________________________________________________________________
        
       Grep flags - the good stuff
        
       Author : U1F984
       Score  : 74 points
       Date   : 2022-02-02 16:13 UTC (6 hours ago)
        
 (HTM) web link (zwischenzugs.com)
 (TXT) w3m dump (zwischenzugs.com)
        
       | nickcw wrote:
       | My favorite feature is:                      -P, --perl-regexp
       | Interpret I<PATTERNS> as Perl-compatible regular
       | expressions (PCREs). This option is experimental when
       | combined with the -z (--null-data) option, and grep -P
       | may warn of unimplemented features.
       | 
       | As everything (python, Go, javascript, etc, etc) uses perl
       | regexps now-a-days and I can never remember which things I need
       | to escape for old gods regexp.
        
         | kjeetgill wrote:
         | Haha, agreed 100%. My go to for years had been
         | https://www.regexplanet.com/. It let's you test what regex
         | escapes work where without spinning up one-off `void main()s`.
        
       | jjoonathan wrote:
       | It's weirdly difficult to get grep to search for fixed binary
       | strings, with lots of gotchas if you don't understand grep
       | internals. I still don't, but this is the best I have been able
       | to do after knocking my forehead on three or four of said
       | gotchas:                   LC_ALL=C grep -larP '\x1A\x2B\x3C\xFF'
        
       | beembeem wrote:
       | "-Irs/-Iirs --color=always" is my standard set of flags
       | 
       | -l/-h/-v/-o show up every now and then
        
       | js2 wrote:
       | In my PATH I have this script as git-gsr, which I can call as
       | "git gsr".                   #!/bin/sh                  usage ()
       | {             cat >&2 <<'__USAGE__'         usage: git gsr [-P |
       | --perl-regexp] <old> <new> [paths...]                    replace
       | all occurrances of <old> with <new> optionally limited to
       | <paths...> (as interpreted by git grep)                    -P,
       | --perl-regexp     interpret <old> as perl regular expression;
       | default is to treat it as a fixed string.
       | __USAGE__             exit 1         }
       | pattern='-F'         perl='BEGIN {($old, $new) = (shift, shift)}
       | s/\Q$old\E/$new/g'                  case "$1" in
       | -P|--perl-regexp)                 shift
       | pattern='-P'                 perl='BEGIN {($old, $new) = (shift,
       | shift)} s/$old/$new/g'                 ;;             -*) usage
       | ;;         esac         test $# -lt 2 && usage         old=$1;
       | new=$2; shift; shift         git grep -l -z $pattern "$old" --
       | "$@" |         xargs -0 perl -pi -e "$perl" "$old" "$new"
        
       | inetknght wrote:
       | My grep is almost always:                   grep -nRI foo ./
       | 
       | Sometimes I add `-i`
       | 
       | Often I will add `-P` and encase the regex with single-quotes of
       | course
        
       | CalChris wrote:
       | I have a shell alias/function variations of which I've used for
       | decades. This is the zsh version:                 function fvi {
       | grep -rl $1 . | xargs nvim +/$1 }
       | 
       | It greps a directory recursively and opens files which have a
       | pattern and puts the pattern in the search buffer.
        
       | chaps wrote:
       | Grep is nice and I've used it daily, but damn does it need multi
       | threading! Especially for recursive greps. I find myself doing
       | this a heck of a lot these days:                 find . -type f
       | -name \*txt \; | xargs -I{} -P24 bash -c "grep -Hi foo '{}' ; :"
        
       | tptacek wrote:
       | Honorable mention for `-q`, which is useful in shell scripts when
       | you don't want the output, just the result code.
        
         | cjcampbell wrote:
         | I am a big fan of the `if [!] grep -q ...` pattern. I'd
         | probably rank -q near the top of the list for shell scripts.
        
       | aidenn0 wrote:
       | I think I have never used grep -r. I'm sure gnu grep has some way
       | to specify which files to search, but why would I learn that
       | syntax as well when I already know find, and exec works (exec +
       | is much faster, but exec ; gets you the results too if your find
       | lacks exec +).
        
         | throwawayboise wrote:
         | Yep, find ... | xargs grep ... is something I use almost daily.
         | I don't use -exec with find, mostly just because I learned the
         | xargs way and it's habit.
        
         | bloopernova wrote:
         | Check out ripgrep
        
           | nicholasjarnold wrote:
           | ...you beat me to it! RipGrep[0] is among my favorite semi-
           | recently discovered CLI tools.
           | 
           | [0] - https://github.com/BurntSushi/ripgrep#why-should-i-use-
           | ripgr...
        
           | aidenn0 wrote:
           | I'm aware of rg, ag, &c. these tools. I even wrote a clone of
           | ag in shell using find/grep/xargs (the last one being needed
           | to get parallelism to match ag's speed).
        
       | mmh0000 wrote:
       | An amazing grep trick that I use all the time: The -e flag can be
       | used to search for multiple terms. A blank -e will search for
       | null. Thus:
       | 
       | Lets assume we have a log file with a bunch of relevant stuff, I
       | want to highlight my search term, BUT I also want to keep all the
       | other lines around for context:                 $ dmesg
       | ...SNIP...       [2334597.539661] sd 1:0:0:0: [sdb] Attached SCSI
       | removable disk       [2334597.548919] sd 1:0:0:0: [sdb] 57280429
       | 512-byte logical blocks: (29.3 GB/27.3  GiB)
       | [2334597.761895] sd 1:0:0:0: [sdb] Write cache: enabled, read
       | cache: enabled, doesn't support DPO or FUA       [2334597.761900]
       | sdb: detected capacity change from 0 to 57280429
       | [2334597.772736]  sdb:       [2334631.115664] sdb: detected
       | capacity change from 57280429 to 0       ...SNIP...
       | 
       | A simple grep, will only return the selected lines:
       | $ dmesg | grep capacity       [2334597.761900] sdb: detected
       | capacity change from 0 to 57280429       [2334631.115664] sdb:
       | detected capacity change from 57280429 to 0
       | 
       | But I want all lines:                 $ dmesg | grep --color -e
       | capacity -e ''       ...SNIP...       [2334597.539661] sd
       | 1:0:0:0: [sdb] Attached SCSI removable disk
       | [2334597.548919] sd 1:0:0:0: [sdb] 57280429 512-byte logical
       | blocks: (29.3 GB/27.3  GiB)       [2334597.761895] sd 1:0:0:0:
       | [sdb] Write cache: enabled, read cache: enabled, doesn't support
       | DPO or FUA       *[2334597.761900] sdb: detected capacity change
       | from 0 to 57280429*       [2334597.772736]  sdb:
       | *[2334631.115664] sdb: detected capacity change from 57280429 to
       | 0*       ...SNIP...
       | 
       | The null trick also works well on directories with many small
       | files, like _/ proc/_ or _/ sys/_. Say, for example, you wanted
       | to get the filename and value of each file:                 $
       | grep -R '' /sys/module/iwlwifi/parameters/
       | /sys/module/iwlwifi/parameters/nvm_file:(null)
       | /sys/module/iwlwifi/parameters/debug:0
       | /sys/module/iwlwifi/parameters/swcrypto:0
       | /sys/module/iwlwifi/parameters/power_save:N
       | /sys/module/iwlwifi/parameters/lar_disable:N       ...SNIP...
        
         | addingnumbers wrote:
         | I always used "-e ^" the same way you're using a null string,
         | to show all lines of the files, each prefixed with the path and
         | filename. Are they equivalent or is there a caveat I should
         | watch out for?
        
           | likpok wrote:
           | Zsh (and possibly other shells?) will expand a raw ^ into
           | filenames. '' is a little shorter than '^' if you have to
           | quote it.
        
             | jolmg wrote:
             | > and possibly other shells?
             | 
             | Years ago--I don't if it's still the case--but the fish
             | shell used ^ to redirect stderr.
             | 
             | EDIT: I remembered right:
             | 
             | https://web.archive.org/web/20111111003423/http://fishshell
             | ....
             | 
             | but it seems it's no longer the case:                 fish>
             | echo foo ^ bar       foo ^ bar
             | 
             | https://fishshell.com/docs/current/tutorial.html#pipes-
             | and-r...
        
         | pjungwir wrote:
         | I have this in my ~/bin, but I like your version even better!:
         | grep --color "$1"'\|$'
        
         | throwawayboise wrote:
         | Since you're probably (or at least often) pipelining this into
         | "less" assuming there is more than one screenful of lines, why
         | not just use the regexp searching/highlighting built into less?
        
       | milliams wrote:
       | I have problems remembering the mnemonic for -A and -B. I can't
       | get it straight whether it's "before" and "after" or "above" and
       | "below". I always just try one then the other!
        
         | VTimofeenko wrote:
         | The way I remember this is by keeping in mind that grep
         | processes the area of the search as a stream of discrete lines
         | by looking at each line individually. "Above/below" are
         | concepts on the stream level, and "after/before" are on the
         | line level.
        
         | ______-_-______ wrote:
         | I've never had trouble remembering, but after reading this
         | comment I'm afraid I might start :(
         | 
         | (joking)
        
         | waynesonfire wrote:
         | A after, B before, C context (for both)
        
         | indigodaddy wrote:
         | Same!
        
       | declnz wrote:
       | I feel `grep -e` (at least) should have been the default in
       | retrospect
       | 
       | Living without those few "extensions" feels... empty
        
       | throwawayboise wrote:
       | It's good to be aware that gnu grep has a lot more features than
       | "unix" grep, so if you find yourself on a BSD system a lot of
       | this stuff doesn't work.
        
       | simon04 wrote:
       | https://explainshell.com/explain?cmd=grep+-rilIv
        
         | cjcampbell wrote:
         | And explainshell might be my favorite discovery of the day. I
         | hadn't stumbled on it before now. I think it'll be helpful for
         | folks I mentor/train. I do push everyone toward using the man
         | pages directly, but I can see how this would be less
         | intimidating for a beginner.
        
       | notatoad wrote:
       | i've had this stuck to my office wall for a while, and i've
       | internalized most of it by now but it's still great
       | 
       | https://twitter.com/b0rk/status/991880504805871616
        
       | zwieback wrote:
       | Ah, learned the difference between -i and -I.
       | 
       | I also like --include and --exclude, especially since it allows
       | regex for which files to look at
        
         | rustyminnow wrote:
         | If you need to include/exclude multiple things, you can go
         | `grep pat --exclude={foo,bar,baz}` which expands to: `grep pat
         | --exclude=foo --exclude=bar --exclude=baz`. Much easier than
         | typing out the flag multiple times
        
           | zwieback wrote:
           | or even something like --exclude={foo,ba[rz]} , probably
           | getting the syntax wrong
        
       | waynesonfire wrote:
       | very frequently I want to chain grep things... I lean on the "|"
       | operator for this, e.g. cat hello | grep foo | grep bar and it
       | seems verbose. any tips?
        
         | danadam wrote:
         | With _sed_ instead of _grep_ , and probably not much better,
         | but in a single command:                 cat hello | sed -n
         | '/foo/{ /bar/{ /baz/ p }}'
        
           | ravoori wrote:
           | with awk: <hello awk '/foo/ && /bar/ && /baz/'
        
         | xorcist wrote:
         | That kind of matches are what regexps were intended for:
         | grep "foo.*bar" hello
         | 
         | Unfortunately, the basic grep syntax doesn't give you an easy
         | way of specifying both orders, so that would have to be
         | something like:                 grep -e "foo.*bar" -e
         | "bar.*foo" hello
         | 
         | You can specify random order in a couple of different ways with
         | Perl-compatible regexes, such as lookaheading the search terms
         | from the end of line marker. But it's not as easy to read as it
         | should be.
        
       | pavon wrote:
       | Learning about -o has decreased my use of sed considerably. Where
       | I used to use:                   sed -n 's/.*\(pattern\).*/\1/p'
       | 
       | it can instead simply be:                   grep -o 'pattern'
       | 
       | The -w flag is new to me today - excited to save still more
       | keystrokes!
        
       ___________________________________________________________________
       (page generated 2022-02-02 23:01 UTC)