1

I am new to AWK. I am trying to format names in a file named names.txt to output the names arranged in a certain way with some of them capitalized and then the output put into an HTML table. See below.

names.txt

KOVACS PETER
Kiss Roland
Nagy jolan
Lisztes Tibor
Feher aNDRas
Korma Maria
Akarki Jack

The output of the names after running the AWK should be as below.

Kovacs Peter        Lisztes Tibor       Akarki Jack
Kiss Roland         Feher Andras
Nagy Jolan          Korma Maria

Here is the AWK code I have written so far in my trial.awk file.

BEGIN{
    FS=OFS=" ";
}{

    s=tolower($0);
    split (s, letters, " ");
    array[arraylen++] = toupper( substr( letters[1], 1, 1 )  ) substr( letters[1], 2 ) " " toupper( substr( letters[2], 1, 1 )  ) substr( letters[2], 2 );
    up=toupper(substr(s,1,1));
    small=tolower(substr(s,1,1));
    as=sub(/small/, up, s);

}

END{
r=0;
for(rows=1;rows<=3;rows++){
    for(columns=r;columns<=r+6;columns+=3){
        printf("%s \t ",array[columns]);
    }r=r+1;
    columns=r;

    printf("\n");
}
}

I want to run it as below and redirect the output into an HTML file with each name in a separate table cell. The remaining part is putting the output in the HTML file otherwise the names are already arranged and capitalized as needed in the code above. Kindly help. Thank you. Let us do this. awk -f trial.awk names.txt > output.html

What is required is that the output from the code above is posted into an HTML file using AWK with each name in a separate cell. awk -f trial.awk names.txt > output.html

2 Answers 2

2

Could you please try following, written and tested with shown samples.

awk -v total=1 '
BEGIN{
  print "<html>" ORS "<title>" ORS "Morris Muuo answer" ORS "</title>"
  print "<head>" ORS "<style>" ORS "table, th, td {" ORS "  border: 1px solid black;" ORS "}" ORS "</style>"
  print "</style>" ORS "<body>" ORS "<table>"
}
{
  ++count
  a[count]=(a[count]?a[count] "\t":"")$0
}
FNR%3==0{
  total++
  count=""
}
END{
  for(i=1;i<=total;i++){
    print "<tr>"
    num=split(a[i],array,"\t")
    for(j=1;j<=num;j++){
       print "<td>" ORS array[j] ORS "</td>"
    }
    print "</tr>"
  }
  print "</table>" ORS "</body>" ORS "</html>"
}'  Input_file


Explanation: Adding detailed explanation for above code.

awk -v total=1 '                                                         ##Starting awk program from here, creating variable total with value 1 for it.
BEGIN{                                                                   ##Starting BEGIN section of this code from here.
  print "<html>" ORS "<title>" ORS "Morris Muuo answer" ORS "</title>"   ##Printing starting of html, title here, please set title as per your need.
  print "<head>" ORS "<style>" ORS "table, th, td {" ORS "  border: 1px solid black;" ORS "}"  ###Printing style tag and setting CSS for table here.
  print ORS "</style>" ORS "<body>" ORS "<table>"                        ##Printing style tag completion and starting body, table tags here.
}
{
  ++count                                                     ##Increasing value of variable count with 1 here.
  a[count]=(a[count]?a[count] "\t":"")$0                      ##Creating array a with index of variable count and keep concatenating current line to it.
}
FNR%3==0{                                                     ##Checking condition if current line is fully divided by 3 here then do following.
  total++                                                     ##Increasing variable total with 1 here.
  count=""                                                    ##Nullify count here.
}
END{                                                          ##Starting END block for this code from here.
  for(i=1;i<=total;i++){                                      ##Starting a for loop which runs from 1 to till value of total value.
    print "<tr>"                                              ##Printing tr tag here.
    num=split(a[i],array,"\t")                                ##Splitting current value of array a value with index i into array with delimiter TAB here.
    for(j=1;j<=num;j++){                                      ##Running for loop till length of array then do following.
       print "<td>" ORS array[j] ORS "</td>"                  ##Printing td tag then value of array and closing tag td here.
    }
    print "</tr>"                                             ##Printing closing tr tag here.
  }
  print "</table>" ORS "</body>" ORS "</html>"                ##Printing all table, body and html tag here.
}' Input_file                                                 ##Mentioning Input_file name here.
Sign up to request clarification or add additional context in comments.

Comments

1

You just need to print out the HTML

END {
    columns = 3
    print "<table>"
    for (rows = 0; rows < columns; rows++) {
        printf "<tr>"
        for (cell = rows; cell <= rows + 2*columns; cell += columns) {
            printf "<td>%s</td> ", array[cell]
        }
        print "</tr>"
    }
    print "</table>"
}

outputs

<table>
<tr><td>Kovacs Peter</td> <td>Lisztes Tibor</td> <td>Akarki Jack</td> </tr>
<tr><td>Kiss Roland</td> <td>Feher Andras</td> <td></td> </tr>
<tr><td>Nagy Jolan</td> <td>Korma Maria</td> <td></td> </tr>
</table>

I can't think of a quick way to explain it, so here's the answer. I'm using seq to just generate 40 items. Unfortunately, awk doesn't ship with a ceil function, so I've added one:

seq 40 | awk -v columns=3 '
    function ceil(n,   i) {
        i = int(n)
        return (n > i ? i + 1 : i)
    }
    { array[arraylen++] = $1 }
    END {
        nr = ceil(arraylen / columns)
        for (row = 0; row < nr; row++) {
            for (idx = row; idx < arraylen; idx += nr) {
                printf "%s\t", array[idx]
            }
            print ""
        }
    }
'

produces

1   15  29
2   16  30
3   17  31
4   18  32
5   19  33
6   20  34
7   21  35
8   22  36
9   23  37
10  24  38
11  25  39
12  26  40
13  27
14  28

4 Comments

Hello, how do you make it print more rows hence printing more names? Let us say I have 40 names. Thank you.
That's just a math exercise: let nr be the number of records, then the number of rows is ceil(nr / columns) -- and the inner loop requires a bit of arithmetic to get the right indices into the array.
The inner loop arithmetic is what am trying to figure out. I am quite new to AWK.
I am trying to make it work with your code. Unsuccessfully.

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.