I have a bunch of files that all follow the same pattern of data.

Let's say that this is the pattern i want to extract from:

First part of text...patternA......Second part of text.....patternB.....Third part of text....patternC.....End part of text

Currently i am using this:

grep -P -o ".{0,5}patternA|.{0,5}patternB.{0,5}|patternC.{0,5}" filename.txt

With this the output i am getting is :

1111 patternA
2222 patternB 2222
patternC 3333

The output i actually want is :

1111 patternA 2222 patternB 2222 patternC 3333

I can't seem to figure out how to get rid of the newlines at the end of each pattern.

How can i accomplish this?

  • 3
    The man page is pretty clear: -o, --only-matching: Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line. Mar 17 '17 at 17:46
  • 1
    grep -o 'pattern' 'file' | column
    – DopeGhoti
    Mar 17 '17 at 17:47

Use sed to copy the parts of the line that match the pattern to the output, using capture groups.

sed -r -n 's/.*(.{0,5}patternA).*(.{0,5}patternB.{0,5}).*(patternC.{0,5}).*/\1 \2 \3/p' filename.txt

This assumes that the patterns are always in this order on the lines.


With column:

COLUMN(1)                 BSD General Commands Manual                COLUMN(1)

     column -- columnate lists

     column [-tx] [-c columns] [-s sep] [file ...]

     The column utility formats its input into multiple columns.  Rows are
     filled before columns.  Input is taken from file operands, or, by
     default, from the standard input.  Empty lines are ignored.

For example (with a free useless use of cat to demonstrate that you can pipe grep's output into column):

$ cat example
$ cat example | column
Fuzzy   wuzzy   was a   bear
  • This will combine output onto the same line even if it wasn't in the same line in the input file.
    – Barmar
    Mar 17 '17 at 20:24
  • The OP explicitly asked for all of the newlines to be removed; what did you expect?
    – DopeGhoti
    Mar 17 '17 at 20:39
  • I didn't ask for anything. He asked that it not break up the lines.
    – Barmar
    Mar 17 '17 at 20:40
  • The example "This is what I want" output example shows all of the output combined onto the same line.
    – DopeGhoti
    Mar 17 '17 at 20:42
  • He just showed the output for one line of input. Presumably the file has more than one line that matches the pattern.
    – Barmar
    Mar 17 '17 at 20:44

if you know all 3 fields always exist, you could try the following with "paste"

grep -P -o ".{0,5}patternA|.{0,5}patternB.{0,5}|patternC.{0,5}" filename.txt | paste - - -

  • This was useful for me when I wanted to print only the integers from each line of a file, where each line had exactly 5 integers and other unneeded text. grep -o -E -- '-?[0-9]+' file | paste - - - - - Nov 9 '20 at 20:31

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.