Loop to convert text output in the HTML format

Hello Everyone,

I have a sample file raw.txt as shown below :

Drive Bays

      Bay Name                             :    SD-2C
      Number of Standby Power Supplies     :    4
      Number of Drive Enclosures           :    12

      Summary Status of Contained Modules
        All Enclosures                     :    Normal
        All Link Control Cards             :    Normal
        All Power Supplies                 :    Normal
        All Standby Power Supplies         :    Normal

      Bay Name                             :    SD-2D
      Number of Standby Power Supplies     :    3
      Number of Drive Enclosures           :    16

      Summary Status of Contained Modules
        All Enclosures                     :    Normal
        All Link Control Cards             :    Normal
        All Power Supplies                 :    Normal
        All Standby Power Supplies         :    Normal

      Bay Name                             :    SD-2F
      Number of Standby Power Supplies     :    3
      Number of Drive Enclosures           :    12

      Summary Status of Contained Modules
        All Enclosures                     :    Normal
        All Link Control Cards             :    Normal
        All Power Supplies                 :    Normal
        All Standby Power Supplies         :    Normal

      Bay Name                             :    SD-2G
      Number of Standby Power Supplies     :    6
  I want to check for the number of fields \( Field separater is ":"\) and convert the file contents in HTML format .If there is 1 field \(no ":" sign is present for example in case of Drive bays from the file\) then 
echo "<tr><td>$arr[0]</td></tr>" 

should be printed
where arr[0] is the first field and in case of two fields (for example in case of Bay Name : SD-2C) following should be printed :

echo "<tr><td>$arr[0]</td><td>$arr[1]</td></tr>"

I tried following to get the number of fields but I am stuck and not getting correct number of fields. Also I got correct number of fields without using :
read -a arr IFS=':' but I have to use this code to create array

while read line
do
read -a arr IFS=':'
count=`echo "$line" | awk -F":" '{print NF}'`
echo $count
done < raw.txt

Please help

Hello rahul2662,

Could you please try following and let me know if this helps you, not tested though. Please let me know if you have any queries on same.

awk -F"[[:space:]]+:[[:space:]]+" 'NF>1{sub(/^[[:space:]]+/,X,$0);for(i=1;i<=NF;i++){Q=Q?Q OFS "<td>" $i "</td>":"<td>" $i "</td>"};print "<tr>" Q "</tr>";Q="";next} NF==1{sub(/^[[:space:]]+/,X,$0);print "<tr><td>"$0"</td></tr>"}' OFS=""   Input_file
 

Output will be as follows.

<tr><td>Drive Bays</td></tr>
<tr><td>Bay Name</td><td>SD-2C</td></tr>
<tr><td>Number of Standby Power Supplies</td><td>4</td></tr>
<tr><td>Number of Drive Enclosures</td><td>12</td></tr>
<tr><td>Summary Status of Contained Modules</td></tr>
<tr><td>All Enclosures</td><td>Normal</td></tr>
<tr><td>All Link Control Cards</td><td>Normal</td></tr>
<tr><td>All Power Supplies</td><td>Normal</td></tr>
<tr><td>All Standby Power Supplies</td><td>Normal</td></tr>
<tr><td>Bay Name</td><td>SD-2D</td></tr>
<tr><td>Number of Standby Power Supplies</td><td>3</td></tr>
<tr><td>Number of Drive Enclosures</td><td>16</td></tr>
<tr><td>Summary Status of Contained Modules</td></tr>
<tr><td>All Enclosures</td><td>Normal</td></tr>
<tr><td>All Link Control Cards</td><td>Normal</td></tr>
<tr><td>All Power Supplies</td><td>Normal</td></tr>
<tr><td>All Standby Power Supplies</td><td>Normal</td></tr>
<tr><td>Bay Name</td><td>SD-2F</td></tr>
<tr><td>Number of Standby Power Supplies</td><td>3</td></tr>
<tr><td>Number of Drive Enclosures</td><td>12</td></tr>
<tr><td>Summary Status of Contained Modules</td></tr>
<tr><td>All Enclosures</td><td>Normal</td></tr>
<tr><td>All Link Control Cards</td><td>Normal</td></tr>
<tr><td>All Power Supplies</td><td>Normal</td></tr>
<tr><td>All Standby Power Supplies</td><td>Normal</td></tr>
<tr><td>Bay Name</td><td>SD-2G</td></tr>
<tr><td>Number of Standby Power Supplies</td><td>6</td></tr> 

Thanks,
R. Singh

1 Like

Try also

awk     'BEGIN  {printf "<html><body><table width=\"600\" border=\"3\" align=\"center\">\n"}
                {gsub (/  +/, _)
                 printf "<tr>"
                 for (i=1; i<=NF; i++) printf "<td>%s</td>", $i
                 printf "</tr>\n"
                }
         END    {printf "</table></body></html>\n"}
        ' FS=: file

---------- Post updated at 10:39 ---------- Previous update was at 10:29 ----------

Try also this adaption to your shell approach:

while read line; do echo "<tr><td>${line//:/<\/td><td>}</td></tr>"; done <file
1 Like

Thanks a lot Ravinder ,

Also I need one small change in the Output.

In case of Drive bays and Summary Status of Contained Modules we need to have the following column : Value as well and output should look like below

<tr><td>Drive Bays</td><td>Value</td></td>
<tr><td>Summary Status of Contained Modules</td><td>Value</td></tr>

Could you also please explain me the code.

Thanks
Rahul

Edit : I got the value (column) as well after adding making small change in the code

Hello rahul2662,

Following is the explanation for same which may help you, let me know if you have any queries on same.

awk -F"[[:space:]]+:[[:space:]]+"                 ####### Making field seprator as space till colon and then space 
'NF>1{                                            ####### If Number of fields are greater than 1  
sub(/^[[:space:]]+/,X,$0);                        ####### Now subsituting the initial space of each line to NULL.
for(i=1;i<=NF;i++){                               ####### Now going to each field of line by for loop.
Q=Q?Q OFS "<td>" $i "</td>":"<td>" $i "</td>"};   ####### NOw creating a variable named Q whose value is equal to "<td>" value of field($i) "</td>" first time then it will keep append value to variable itself which is Q till number of fields are completed for that particular line.
print "<tr>" Q "</tr>";                           ####### Now printing the strings "<tr>" then value of variable Q "</tr>"
Q="";                                             ####### Nullifying the value of Q as next line it should not append previous values of Q.
next}                                             ####### Now using next statment of awk and skipping all further statments now.
NF==1{                                            ####### When number of fields are 1.
sub(/^[[:space:]]+/,X,$0);                        ####### When above condition is TRUE then substitute initial space of each line to NULL.
print "<tr><td>"$0"</td></tr>"}'                  ####### Now printing strings "<tr><td>" value of line "</td>"</tr>".
OFS="" Input_file                                 ####### Setting output field seprator to NULL now and mentioning Input_file.
 

Thanks,
R. Singh

2 Likes

Hello Ravinder ,

How can be have the <tr> and <td> tags around a space separated file. For example below is the file :

Ide  Intir TID Grp  Vendor     Type       Hypr      Total       Free
MH-1E    C   4    4 SFGRET     MED7600      44    1823565      36236
Totals                                                          1823565      36235

expected Output is like below. Also the last line has only first field and the last 2 fields.

<tr><td>Ide</td><td>Intir<td><td>TID</td><td>Grp</td><td>Vendor</td><td>Type</td><td>Hypr</td><td>Total</td><td>Free</td></tr>
<tr><td>MH-1E</td><td>C</td><td>4</td><td>4</td><td>SFGRET</td><td>MED7600</td><td>44</td><td>1823565</td><td>36236</td></tr>
<tr><td>Totals</td><td></td><td></td><td></td><td></td><td></td><td></td><td>1823565</td><td>36235</td></tr>

Hello rahul2662,

Following may help you in same.

awk 'NR==1{n=NF;}{if(n==NF){for(i=1;i<=n;i++){A=A?A OFS "<td>"$i"</td>":"<td>"$i"</td>"};print "<tr>"A"</tr>";A=""}} {if(NF<n){for(j=2;j<n-2;j++){B=B?B OFS "<td></td>":"<td></td>"};print "<tr><td>" $1 "</td>" B "<td>" $(NF-1) "</td><td>" $(NF) "</td></tr>"}}' OFS=""   Input_file
 

Output will be as follows.

<tr><td>Ide</td><td>Intir</td><td>TID</td><td>Grp</td><td>Vendor</td><td>Type</td><td>Hypr</td><td>Total</td><td>Free</td></tr>
<tr><td>MH-1E</td><td>C</td><td>4</td><td>4</td><td>SFGRET</td><td>MED7600</td><td>44</td><td>1823565</td><td>36236</td></tr>
<tr><td>Totals</td><td></td><td></td><td></td><td></td><td></td><td>1823565</td><td>36235</td></tr>
 

Here things which we should consider is on first line this code will record the number of fields and then each line it will look for same number of fields.
Also lines which are lesser number of fields then it will always fill strings <td></td> till $(NF-1) fields because you have mentioned only last 2 fields will be there. Could you please check it and let me know if this helps you.

Thanks,
R. Singh

1 Like