Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can grep show matching part of line with "context"? [duplicate]

Tags:

git

grep

sed

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.

like image 598
UlfR Avatar asked Aug 29 '19 13:08

UlfR


People also ask

How do you grep with surrounding lines?

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.

Which grep switch also shows the two lines above and below each match found?

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.

How do you print only the matched pattern using grep?

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.

How do you grep multiple lines after a match?

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!


2 Answers

grep -noE '.{,4}dolor.{,4}' lorem.txt

It returns:

1:sum dolor sit
3: et dolore ma
like image 100
Dmitriy Avatar answered Nov 15 '22 00:11

Dmitriy


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}" "$@"
like image 26
dash-o Avatar answered Nov 15 '22 02:11

dash-o