Say I have this text-file (lorem.txt):
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua.
If I use grep
I can now easily find the row containing eiusmod
by:
$ grep eiusmod lorem.txt
adipiscing elit, sed do eiusmod tempor
By using some sort of context-switch like -C
I can even get the lines surrounding the match:
$ grep -C1 eiusmod lorem.txt
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
This is good. But what if I just want to see some of the characters closest to the match on the same line? Not the full line. So a behaviour like this:
$ grep --char-context=3 eiusmod lorem.txt
do eiusmod te
$ grep -n --char-context=5 dol lorem.txt
1:psum dolor si
3:e et dolore m
I could of course do this with some clever sed, awk or other tool:
$ sed -n '/dol/{=;s/.*\(...dol...\).*/\1/p}' lorem.txt | sed 'N;s/\n/:o/'
1:um dolor
3:et dolore
But that is not what I want. It's too complicated and obscure to be usable on a day-to-day basis. So is there a simpler way or tool to achieve this?
This is mainly a problem when doing recursive grep over files with long lines like minified css or other files with long texts without newlines. I first started thinking about this when using git grep
so a solution usable both for plain grep
and git grep
is preferred.
Note also that a grep-pipe-sed
construct is undesirable since that will remove any highlight/colorisation of the match.
For BSD or GNU grep you can use -B num to set how many lines before the match and -A num for the number of lines after the match. If you want the same number of lines before and after you can use -C num . This will show 3 lines before and 3 lines after.
grep's -A 1 option will give you one line after; -B 1 will give you one line before; and -C 1 combines both to give you one line both before and after, -1 does the same.
Displaying only the matched pattern : By default, grep displays the entire line which has the matched string. We can make the grep to display only the matched string by using the -o option. 6. Show line number while displaying the output using grep -n : To show the line number of file with the line matched.
Use the -A argument to grep to specify how many lines beyond the match to output. And use -B n to grep lines before the match. And -C in grep to add lines both above and below the match!
grep -noE '.{,4}dolor.{,4}' lorem.txt
It returns:
1:sum dolor sit
3: et dolore ma
Solution based on Wiktor Stribiżew comment above.
Possible to create 'grep-cxt', which will take 2 mandatory parameters (# of characters around pattern, pattern) and optional list of files (default: stdin).
#! /bin/bash
count=$1
pattern=$2
shift
shift
grep -E --all-match ".{0,$count}$pattern.{0,$count}" "$@"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With