2

I have a need to document 100+ CSV files as far as the format of those files and including sample data. What I would like to do is take a CSV of the following format:

Name, Phone, State
Fred, 1234567, TX
John, 2345678, NC

and convert it to:

Field | Sample
---   | ----
Name  | Fred
Phone | 1234567
State | TX

Is this possible with AWK? From my example below, you will see I am trying to format as a markdown table. I have it currently transposing the header row with

#!/usr/bin/awk -v RS='\r\n' -f
BEGIN { printf "| Field \t| Critical |\n"}
{
    printf "|---\t|---\t|\n"
    for (i=1; i<=NF; i++) {print "|", toupper($i), "| sample |"}
}
END  {}

But I am not sure now how to use the first row of data, after the header to display the sample data?

1
  • can you give two samples in output at least? Commented Mar 13, 2014 at 1:30

2 Answers 2

1

awk is the right tool for data parsing. You can try something like:

awk '
BEGIN { FS=", "; OFS=" | " }
NR==1 {
    for(tag = 1; tag <= NF; tag++) {
        hdr[tag] = sprintf ("%-7s", $tag)
    }
    next
}
{
    for(fld = 1; fld <= NF; fld++) {
        data[NR,fld] = $fld
    }
}
END {
    print "Field   | Sample\n------- | -------";
    for(rec = 2; rec <= NR; rec++) {
        for(line = 1; line <= NF; line++) {
            print hdr[line], data[rec,line]
        }
    }
}' file

Output:

Field   | Sample
------- | -------
Name    | Fred
Phone   | 1234567
State   | TX
Name    | John
Phone   | 2345678
State   | NC
Sign up to request clarification or add additional context in comments.

3 Comments

Spot on, thank you so much! This is exactly what I was after. I love the Internet and all who share their knowledge on it! Thanks.
Since you are using tag value only one loop, you can replace for(tag = 1; tag <= NF; tag++) with while(tag++<NF)
@Jotne Indeed, just went with the more explicit version.
1

Here is a more simple way to do it with awk
No need to store everything in a array then print at the end.

awk -F", " 'NR==1{split($0,a,FS);print "Field   | Sample\n------- | -------";next} {for (i=1;i<=NF;i++) printf "%-8s| %s\n",a[i],$i}' file
Field   | Sample
------- | -------
Name    | Fred
Phone   | 1234567
State   | TX
Name    | John
Phone   | 2345678
State   | NC

How it works:

awk -F", " '                            # set field separator to ","
NR==1{                                  # if first line do:
    split($0,a,FS)                      # split first line to an array named "a" to get the labels 
    print "Field   | Sample"            # print header
    print "------- | -------"           # print separator
    next}                               # prevents nothing more run for first line
    {                                   # for all lines except first do:
    for (i=1;i<=NF;i++)                 # loop trough all element in line
        printf "%-8s| %s\n",a[i],$i     # print data for every element
    }
' file

Comments

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.