Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I extract using sed or awk between newlines after a specific pattern?

Tags:

sed

awk

I like to check if there is other alternatives where I can print using other bash commands to get the range of IPs under #Hiko other than the below sed, tail and head which I actually figured out to get what I needed from my hosts file. I'm just curious and keen in learning more on bash, hope I could gain more knowledge from the community. :D

$ sed -n '/#Hiko/,/#Pico/p' /etc/hosts | tail -n +3 | head -n -2

/etc/hosts

#Tito

192.168.1.21
192.168.1.119

#Hiko

192.168.1.243
192.168.1.125
192.168.1.94
192.168.1.24
192.168.1.242

#Pico

192.168.1.23
192.168.1.93
192.168.1.121
like image 389
Yong Avatar asked Nov 30 '22 13:11

Yong


2 Answers

1st solution: With shown samples could you please try following. Written and tested in GNU awk.

awk -v RS= '/#Pico/{exit} /#Hiko/{found=1;next} found' Input_file

Explanation:

awk -v RS= '       ##Starting awk program from here.
/#Pico/{           ##Checking condition if line has #Pico then do following.
  exit             ##exiting from program.
}
/#Hiko/{           ##Checking condition if line has #Hiko is present in line.
  found=1          ##Setting found to 1 here.
  next             ##next will skip all further statements from here.
}
found              ##Checking condition if found is SET then print the line.
' Input_file       ##mentioning Input_file name here.

2nd solution: Without using RS function try following.

awk '/#Pico/{exit} /#Hiko/{found=1;next} NF && found' Input_file

3rd solution: You could look for record #Hiko and then could print its next record and come out with shown samples.

awk -v RS= '/#Hiko/{found=1;next} found{print;exit}' Input_file

NOTE: These all solutions above check if string #Hiko or #Pico are present in anywhere in line, in case you want to look exact string then change above only /#Hiko/ and /#Pico/ part to /^#Hiko$/ and /^#Pico$/ respectively.

like image 60
RavinderSingh13 Avatar answered Dec 04 '22 04:12

RavinderSingh13


With sed (checked with GNU sed, syntax might differ for other implementations)

$ sed -n '/#Hiko/{n; :a n; /^$/q; p; ba}' /etc/hosts
192.168.1.243
192.168.1.125
192.168.1.94
192.168.1.24
192.168.1.242
  • -n turn off automatic printing of pattern space
  • /#Hiko/ if line contains #Hiko
    • n get next line (assuming there's always an empty line)
    • :a label a
    • n get next line (using n will overwrite any previous content in the pattern space, so only single line content is present in this case)
    • /^$/q if the current line is empty, quit
    • p print the current line
    • ba branch to label a
like image 24
Sundeep Avatar answered Dec 04 '22 04:12

Sundeep