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?

0

4 Answers 4

4

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
1
  • Wow, how easy, better than to struggel with sed.
    – John Goofy
    Sep 28, 2018 at 14:30
2

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
2
  • @downvoter: please leave a comment.
    – pLumo
    Sep 28, 2018 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, 2018 at 11:20
2

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
2
  • 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... Sep 28, 2018 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. Sep 28, 2018 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)>

4
  • 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.
    – pLumo
    Sep 28, 2018 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, 2018 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.
    – pLumo
    Sep 28, 2018 at 13:12
  • Your answer is the moral equivalent of sed -n '8,11p' or printf '85434\nrdb\n232323\n232435656\n' — they all produce the requested output for the example input in a trivial way, but they don’t solve the problem as described. Dec 30, 2019 at 22:45

You must log in to answer this question.