0

I want to read a file and print it to stdout using shellscript . in python rsplit can do the job but i search and find awk but i cant understand .

file1:

#begin cow
Host cow
    HostName 172.18.0.10
    User root
    Port 22
#end cow
#begin dns2
Host dns2
    HostName 172.20.4.80
    User root
    Port 22
#end dns2
#begin dns1
Host dns1
    HostName 172.20.4.75
    User root
    Port 22
#end dns1
#begin dns3
Host dns3
        HostName 172.20.4.76
        User root
        Port 22
#end dns3
#begin dns4
Host dns4
        HostName 172.20.4.77
        User root
        Port 22
#end dns4
#begin dns5
Host dns5
        HostName 172.20.4.78
        User root
        Port 22
#end dns5
#begin dns6
Host dns6
        HostName 172.20.4.79
        User root
        Port 22
#end dns6

after parsing its turns to

Host: cow  Hostname: 172.18.0.10 User: root Port: 22
Host: dns2 Hostname: 172.20.4.80 User: root Port: 22
Host: dns1 Hostname: 172.20.4.75 User: root Port: 22
Host: dns3 Hostname: 172.20.4.76 User: root Port: 22
Host: dns4 Hostname: 172.20.4.77 User: root Port: 22
Host: dns5 Hostname: 172.20.4.78 User: root Port: 22
Host: dns6 Hostname: 172.20.4.79 User: root Port: 22

any one can help me about this thank you

1
  • Could you be a bit more specific? In your title, you are asking for a solution using shell programming, but then you ask for help with an awk program. Also, it is not clear, where exactly your problem ist. First I thought, you have problems collecting the lines belonging to one host, but then you explicitly mention rsplit. What exactly do you need to know? How to implement rsplit in awk? If yes, which awk are you using (old awk, gawk, ....)? Commented Jan 4, 2016 at 7:47

2 Answers 2

5

Since you haven't mentioned your awk command in the question, i assume u are looking for a solution with awk and an explanation.

AMD$ awk '!/^#/{printf $1": "$2" "}/end/{print '\n'}' File

Host: cow HostName: 172.18.0.10 User: root Port: 22
Host: dns2 HostName: 172.20.4.80 User: root Port: 22
Host: dns1 HostName: 172.20.4.75 User: root Port: 22
Host: dns3 HostName: 172.20.4.76 User: root Port: 22
Host: dns4 HostName: 172.20.4.77 User: root Port: 22
Host: dns5 HostName: 172.20.4.78 User: root Port: 22
Host: dns6 HostName: 172.20.4.79 User: root Port: 22

For all lines NOT beginning with # (!/^#/), printf the 1st and 2nd fields seperated by : and space. Continue this until we hit the end pattern (/end/), where we would print the new line.

In case you are looking for an explanation for the awk command you already have, mention it in the question.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much it helped me can you please if i want to print only one block from this file like cow what awk command can i use ?
Arash Shams : awk '/#begin cow/{v=1}!/^#/&&v{printf $1": "$2" "}/end/&&v{print '\n';v=0}' File . You can upvote and accept the answer if it helped.
i decided to remove #begin and #end so how can i change the command to parse from beginning of Host and end to beginning of another Host means a block like Host dns2 HostName 172.20.4.80 User root Port 22
2

Based on your text (assume structure are complete (begin -> end), there is no empty line, ...)

awk -v "Sep=\t" '/^#begin/{Infos="";next}/^#end/{print Infos;next}{Infos = Infos ($1~/^Host$/ ? "" : Sep) $1 ": " $2}' YourFile

Sep is your separator between info sub sequence.

Same with a filter (only print if filter is the same; here if host is cow or boy)

awk -v "Sep=\t" -v"Filter=^cow$|^boy$" '
   /^#begin/{Infos="";PassFilter=0;next}
   /^#end/&&PassFilter{print Infos;next}
   $1~/^Host$/{PassFilter=$2~Filter}
   {Infos = Infos ($1~/^Host$/ ? "" : Sep) $1 ": " $2}
   ' YourFile

Explanation:

  • /^#begin/{Infos="";next} reset string to print every line starting by `#begin, go to next line of source file (don't treat following instruction).
  • /^#end/&&PassFilter{print Infos;next} when line start with #end and the variable PassFilter is true (=1), print the string content of Infos, go to next line of source file.
  • $1~/^Host$/{PassFilter=$2~Filter} when line first word is Host, the variable PassFilter is set to true if second word contains/corresponds to the regex into Filter variable (^cow$|^boy$ in this case).
  • {Infos = Infos ($1~/^Host$/ ? "" : Sep) $1 ": " $2} Add content of the current line (first ($1) then : and finally second word in fact) to variable Infos with a separator if not line withHost` as first word.

6 Comments

Thank you its very helpful but how can i control tabs between parameters
if i want to print only one block from this file like cow what awk command can i use ?
You need to add a filter on block . In this structure best if before printing. 2 choice, filter the block or in the block. I show sample inside the block (easy to adapt)
can you give me a sample please i can figure out
with some basic explaination
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.