3

I am trying to use grep to find all matching strings in file and output them, in context of the line, to another file, while adding some kind of marks (ideally two asterisks) on each side of the match.

For example, I have input.txt file with following contest:

Dog walks in the park
Man runs in the park
Man walks in the park
Dog runs in the park
Dog is still
They run in the park
Woman runs in the park

Then, I do grep search with redirection to the file:

grep -P ' runs? ' input.txt > output.txt

It creates output.txt file with following contest:

Man runs in the park
Dog runs in the park
They run in the park
Woman runs in the park

What I would like to do instead is to get that output:

Man **runs** in the park
Dog **runs** in the park
They **run** in the park
Woman **runs** in the park

That is, to each match in context add two asterisks around that match.

I know I can get only matches by adding -o option:

grep -P ' runs? ' input.txt > output.txt

but I need to see them in context.

I also know that I can highlight those matches in interactive session by running this:

GREP_OPTIONS='--color=auto'

but I am using grep inside of bash script, so it is of no use to me.

So I am wondering if there is any way to mark those matches in output file, directly with grep. I know that I probably could later pipe grep output to different command to achieve that, but I would prefer to use some grep option. Is it possible? If not, what is most straightforward way to achieve my desired output while combining grep with other tools?

  • 1
    grep doesn't do replacement: you'd be better using sed or perl e.g. sed -n 's/\<runs\>/**&**/p' input.txt > output.txt – steeldriver Jul 21 '15 at 12:27
  • @steeldriver I actually wanted to use perl one-liner at first, but I need to pass regex as function argument, which caused some issues with perl, but worked fine with grep. This is of course issue for another question, but I thought that maybe there is some option of grep that allows for adding such marks. Even though technically it is replacement, I thought maybe it is possible. That would be simpler for me than solving the other issue. – Rafal Jul 21 '15 at 12:30
  • 2
    Sounds like an XY problem then – steeldriver Jul 21 '15 at 12:33
  • 2
    That's the definition of XY problem; you can't get something to work and you try to go around it asking for what you think could be an alternative solution instead of just asking about the original problem; this usually leads to an excalation of consecutive problems (although probably not in this case). If you can't stand going without grep, you're out of luck, since there's no way of doing this with grep, it's simply not designed for that. If sed, Perl or awk don't work for your only choice is to ask a question about the original problem. – kos Jul 21 '15 at 13:13
  • 1
    @kos You and steeldriver are right. I asked another question about my original problem with perl and were able to fix all that thanks to it and your answer. (Question was asked here: stackoverflow.com/questions/31557677/…) – Rafal Jul 22 '15 at 16:17
5

You want to use other tools to perform substitutions, such as sed:

sed -n 's/ \(runs\?\) / **\1** /p' input.txt > output.txt

Or Perl:

perl -ne 's/ (runs?) / **$1** /&&print' input.txt > output.txt
  • short and precise =) – A.B. Jul 27 '15 at 18:06

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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