0

This question already has an answer here:

I know there's the a syntax you can use, like:

grep -oP '.word1.*?word2'

but this doesn't work on multiple lines. So here's an example input:

user1:x:1001:1001::/home/user1home:/bin/bash
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash

The command I tried to use was:

grep -oP '.1002:1002.*?user4home'

My desired output would be something like this:

1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home

marked as duplicate by αғsнιη, Michael Homer, Prvt_Yadav, Mr Shunz, roaima May 2 at 20:21

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

0

With a file z2 containing:

user1:x:1001:1001::/home/user1home:/bin/bash
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash first
user1:x:1001:1001::/home/user1home:/bin/bash
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash second

The utility cgrep will produce:

$ cgrep -e '1002:1002' +w '/home/user4home' z2
========================================
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash first
========================================
user2:x:1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home:/bin/bash second

More information on cgrep (context, windowing grep):

cgrep   shows context of matching patterns found in files (man)
Path    : ~/executable/cgrep
Version : 8.15
Type    : ELF 64-bit LSB executable, x86-64, version 1 (SYS ...)
Home    : http://sourceforge.net/projects/cgrep/ (doc)

Best wishes ... cheers, drl

0

You can use:

grep -Pzo "1002:1002.*(\n|.)*/home/user4home" file

It will match word starting with 1002:1002, till /home/user4home.

  • Thanks, that's awesome, can you please explain what each part does? :D – Farcas Paul Apr 30 at 15:59
  • @Farcas, read the man page to learn what -z does. – glenn jackman Apr 30 at 16:13
0

You can use pcregrep:

$ pcregrep -Mo "(?s)1002:1002.*/home/user4home" file
1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home

The (?s) modifier (which may also be used in grep -P) makes . include \n so that there is no need to match newlines explicitly.

0

Or you convert the file to one line and convert it back.

$ cat file | tr \\n \\0 | grep -oa '1002:1002.*user4home' | tr \\0 \\n
1002:1002::/home/user2home:/bin/bash
user3:x:1003:1003::/home/user3home:/bin/bash
user4:x:1004:1004::/home/user4home

You need to add -a to grep to treat binary files as text.

  • nice! But note the UUOC. < file tr \\n \\0 ... works well. – William Pursell Apr 30 at 17:24

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