I'm looking to do a find and replace within a giant database dump, and it's not doing what I think should happen. I'd like to grep for my target string in the file, and then see the surrounding 8 characters or so (I might need to adjust that number, depending). How can I do that?

The reason I can't eyeball this is because there are many hundreds, if not thousands of matches. I want to get some number of characters surrounding the string, and then pipe it into uniq or something to see why my find and replace is having unexpected behaviors.

Also, there can be multiple matches on the same line!

  • It is not a text file?
    – enzotib
    Aug 24 '11 at 20:03
  • It is, but even just the matches are too big a file to eyeball.
    – user394
    Aug 24 '11 at 20:08

The crude way using grep would be something like

grep -o "....yourtext...." /path/to/the/dump.sql

The number of dots corresponds to the number of characters before/after the grepped text. The -o option makes grep output only the matches, not the whole lines.

To use uniq on the output, remember you have to sort the output first. So typically, you'd do

grep . . . | sort | uniq

If you are interested in the hitcount for each match, you can get nice output using

grep . . . | sort | uniq -c | sort -n
  • 1
    Crude? Utterly sophisticated!
    – user394
    Aug 24 '11 at 20:40
  • 1
    You could expand on this a little by using the repeat operator: grep -o '.\{8\}yourtext.\{8\}'. This is a little less dizzying than counting 8 dots.
    – Caleb
    Aug 24 '11 at 20:44
  • :) By crude I mean you don't play with things like counting matched characters (using ranges) or narrowing the character sets. Aug 24 '11 at 20:46
  • @Caleb and user394: This is exactly what I intended not to suggest (and thus called my method "crude"). One does not need to remember the repeat operator construct, besides - it is even faster to type "....." than ".\{6\}". Aug 24 '11 at 20:51

Starting from the answer of @rozcietrzewiacz, I can expand to

grep -on ".\{0,$num\}$pattern.\{0,$num\}" input-file
  • 1
    The "crude" dot sequence is looking better and better all the time :)
    – Caleb
    Aug 24 '11 at 21:30
  • 1
    @Caleb: generally the "crude" answer is a good start, but sometimes one want to elaborate a little bit on it.
    – enzotib
    Aug 25 '11 at 5:47
  • 1
    The dot sequence method won't find left or right justified target patterns; this method will. (+1)
    – Peter.O
    Aug 25 '11 at 12:07
  • 2
    PS.. I just noticed that it won't catch multiples instances of pattern on the same line (as the OP mentioned) when the scope of the trailing 'exta' text of the first pattern overlaps the scope of the leading 'extra' text of the next pattern
    – Peter.O
    Aug 25 '11 at 12:18
  • @fred: yeah, -o gives only the first match when two matches overlap: echo 'aaabbbccc' | grep -o 'bb
    – enzotib
    Aug 25 '11 at 12:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.