2

I'm trying to convert rows into columns in table format.

Server Name            : dev1-151vd
  Status                 : DONE
  Begin time             : 2021-12-20 04:30:05.458719-05:00
  End time               : 2021-12-20 04:33:15.549731-05:00

  Server Name            : dev2-152vd
  Status                 : DONE
  Begin time             : 2021-12-20 04:30:05.405746-05:00
  End time               : 2021-12-20 04:30:45.212935-05:00

I used the following awk script to transpose rows into columns

awk -F":" -v n=4 \
  'BEGIN { x=1; c=0;} 
  ++c <= n && x == 1 {print $1; buf = buf $2 "\n";
       if(c == n) {x = 2; printf buf} next;}
   !/./{c=0;next}
    c <=n {printf "%4s\n", $2}' temp1.txt | \
   paste - - - - | \
   column -t -s "$(printf "\t")"




Server Name                Status                      Begin time                 End time
 dev1-151vd                  DONE                       2021-12-20 04               2021-12-20 04
 dev2-152vd                  DONE                       2021-12-20 04              2021-12-20 04

The above o/p doesn't have proper begin time & End time,Please let me know how to get the formatting right so the time is printed appropriately.

1
  • Never do printf buf for any input as it'll fail cryptically when your input contains printf formatting chars like %s, always do printf "%s", buf instead. Commented Dec 26, 2021 at 12:28

2 Answers 2

1
$ cat tst.awk
BEGIN { OFS="\t" }
NF {
    if ( ++fldNr == 1 ) {
        recNr++
        rec = ""
    }
    tag = val = $0
    sub(/[[:space:]]*:.*/,"",tag)
    sub(/[^:]+:[[:space:]]*/,"",val)
    hdr = hdr (fldNr>1 ? OFS : "") tag
    rec = rec (fldNr>1 ? OFS : "") val
    next
}
{
    if ( recNr == 1 ) {
        print hdr
    }
    print rec
    fldNr = 0
}
END { if (fldNr) print rec }

$ awk -f tst.awk file | column -s$'\t' -t
Server Name  Status  Begin time                        End time
dev1-151vd   DONE    2021-12-20 04:30:05.458719-05:00  2021-12-20 04:33:15.549731-05:00
dev2-152vd   DONE    2021-12-20 04:30:05.405746-05:00  2021-12-20 04:30:45.212935-05:00

The above will work no matter how many lines per record you have in your input and whether you have other :s or %ss or anything else.

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

Comments

0

See this script:

awk -F": " -v n=4 \
  'BEGIN { x=1; c=0;} 
  ++c <= n && x == 1 {print $1; buf = buf $2 "\n";
       if(c == n) {x = 2; printf buf} next;}
   !/./{c=0;next}
    c <=n {printf "%4s\n", $2}' 20211222.txt | \
   paste - - - - | \
   column -t -s "$(printf "\t")"

Output:

Server Name                Status                     Begin time                        End time
dev1-151vd               DONE                       2021-12-20 04:30:05.458719-05:00  2021-12-20 04:33:15.549731-05:00
dev2-152vd               DONE                       2021-12-20 04:30:05.405746-05:00  2021-12-20 04:30:45.212935-05:00

Explanation: In awk, the -F option means field-separator. In your code you used a colon to separate columns from one another. However in your input, some lines have more than 1 colon (i.e. your timestamp field alone has 3 colons) therefore awk interprets these as having 5 columns.

The solution is to add a whitespace to your field separator (": "), since your input does have a whitespace after the first colon and before your second column.

1 Comment

How can i convert the output as html file

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.