Hacker News new | ask | show | jobs
by mmh0000 1597 days ago
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...
3 comments

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?
Zsh (and possibly other shells?) will expand a raw ^ into filenames. '' is a little shorter than '^' if you have to quote it.
> 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...
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?
I have this in my ~/bin, but I like your version even better!:

    grep --color "$1"'\|$'