Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I have two parts of a string that I know, called phrase1 and phrase2 that are in the same line of a file that occur multiple times throughout the file. I need to extract these lines from the file; however, there are numbers in between that I do not know and the lines can vary. For instance, there are lines that may look like:

phrase1 654654 phrase2
phrase1 22 phrase2
phrase1 949 phrase2

etc. 

However, I do know that I can write a code specifically for a particular line. For instance, I can write for line 2 above the following to find it:

grep "phrase1 [0-9][0-9] phrase2" file

What code can I write using grep (or similar) in order to extract all the lines containing both phrase1 and phrase2 without knowing the numbers, or anything else for that matter, in between?

share|improve this question

3 Answers 3

Two methods: with regular expressions:

grep "phrase1 .* phrase2" file

This search for phrase1, one space, a string of characters that could be whatever you want, another space, and the phrase2, anywhere in the line (it matches lines that have more material before "phrase1" and after "phrase2")

If the two phrases have to be at the start and end of the line, see @AndreasT answer: you can use ^ and $ to "anchor" the regular expression at the start and end of the line.

If you want to match just numbers between the two phrases, the answer by minerz029 is the correct one; "[0-9]+" matches a repetition of digit ("+" means "a sequence of at least one character").

If you want just numbers and phrase1 and phrase2 must be at the start and end of the phrase, combine the twos:

grep "^phrase1 [0-9]+ phrase2$" file

Or the "trick"/hack...

grep "phrase1" file | grep "phrase2"

Explication: the first command search for all the occurences of phrase1, then "pipes" the resulting lines as input to the second grep, that outputs all the lines that matches phrase2.

However, as noticed by @AndreasT, this second method matches the reversed "phrase2...phrase1" pattern, which could be unwanted.

share|improve this answer
2  
Your second "trick" would match also the line phrase2 ... phrase1. –  AndreasT Nov 21 '13 at 10:30
1  
?? Both your first method and mine match phrase1...phrase2 but not phrase2...phrase1, as instead your second does. –  AndreasT Nov 21 '13 at 15:07

If the lines you are looking for start with phrase1 and end with phrase2, then I would suggest

grep "^phrase1.*phrase2$"

Here is a list of the special characters used

  • ^ matches the beginning of a line
  • $ matches the end of a line
  • . matches every character
  • * matches 0 or more occurrences of the previous character

So, basically, grep looks for lines beginning with phrase1, followed by 0 or more characters and ending with phrase2.

share|improve this answer

Use this to detect only digits in between the phrases:

grep -E '^phrase1 [0-9]+ phrase2$'

The -E option uses "Extended regular expressions", adding support for the + operator.

Breakdown:

  • ^ means to match the start of the line.
  • + after the [0-9] means to search for one or more occurrences of the preceding expression, which in this case is the class [0-9].
  • $ means to match the end of the line.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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