0

How can I print all data between two matches, staring from specific line after the first match. For example, let's say I have two patterns Linux and Unix and there are entries between these two words I would like to print data from specific line after the word Linux, in the example below line #6 after Linux, until the word Unix:

Linux
12
32
34
556
676
77
85434
rdb
232323
232435656
Unix
98736
4345
4546456
456

expected output:

85434
rdb
232323
232435656

How can I do it using awk, sed and grep?

1

Try this,

awk '/^Linux$/{flag=1;next}/^Unix$/{flag=0}flag' file | tail -n +7

Or without tail:

awk '/^Linux$/{flag=1;n=NR;next}/^Unix$/{flag=0};flag&&NR>(n+6);' file

Explanation:

  • Search for pattern ^Linux$, and if found, set flag to 1 (true) and move directly to next line.
  • Go on until pattern ^Unix$ was found and set flag to 0 (false)
  • The flag at the end is an awk specific notation. If flag is true, print the line, else do nothing.
  • flag is just a variable name and can be anything, e.g. f or printthisline.

Using Gnu sed:

sed '/^Linux$/,/^Unix$/{//!b};d' file | tail -n +7
  • @downvoter: please leave a comment. – RoVo Sep 28 '18 at 11:19
  • Thank you for help it worked for me this is what I want. could you explain awk command please? – user311543 Sep 28 '18 at 11:20
3

Whenever you see relative addressing, you should reach for ed.

echo '/Linux/+7,/Unix/-1p' | ed -s input_file.txt -

Or, as a heredoc:

ed -s input_file.txt - <<\EOF
/Linux/+7,/Unix/-1p
EOF
  • Wow, how easy, better than to struggel with sed. – John Goofy Sep 28 '18 at 14:30
1

I would write one of

sed -n '/Linux/,/Unix/p' file | sed '1,7d;$d'
# or
awk '/Linux/ {nr = NR} /Unix/ {exit} nr && NR > nr+6' file
  • sed -e '/Linux/,/Unix/!d;/Linux/{N;N;N;N;N;N;N;s/.*\n//' -e '}' -e '/Unix/d' so as to avoid pipes and two sed invocations though really, sed should be avoided anytime one has to count stuff... – don_crissti Sep 28 '18 at 14:35
  • 1
    Yeah, I was fooling around with sed and loops, trying to cram it into a single sed program before I decided it wasn't worth the effort. – glenn jackman Sep 28 '18 at 14:44
0

if you search with grep you can do this:

  • grep -A 5 "string used to search" <path-to-file(s)> will show the 5 lines after the matched string
  • grep -B 5 "string used to search" <path-to-file(s)> will show the 5 lines before the matched string
  • grep -C 5 "string used to search" <path-to-file(s)> will show the 5 lines after and before the matched string (C stands for context)

for your example, it would be: grep -A 2 -B 1 "rdb" <path-to-file(s)>

  • He wants to search key words Linux and Unix, not rdb. Although I think he doesn't know how many lines will lie in between. – RoVo Sep 28 '18 at 11:20
  • given his statement: How can I print all data between two matches, staring from specific line after the first match. and his expected output, I wanted to make it simple. I guess your assumption Although I think he doesn't know how many lines will lie in between. was correct, but what I provided is not incorrect as per his request, is it? – Kramer Sep 28 '18 at 12:47
  • yes it is incorrect, as OP says "For example, let's say I have [...]" which tells me that his text is just an example and not the real text. While your solution works for his example, it might not work for his real text. – RoVo Sep 28 '18 at 13:12

Your Answer

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