1

Actually I have csv file with suppose 20 headers and they have corresponding values for those headers in the next row for a particular record. Example : Source file

Age,Name,Salary
25,Anand,32000

I want my output file to be in this format. Example : Output file

Age
25
Name
Anand
Salary
32000

So for doing this which awk/grep/sed command to be used?

2
  • Show us what you tried so far. Commented Mar 7, 2015 at 10:44
  • 1
    Is your input just 2 lines, or do you have multiple pairs of header/data lines? Commented Mar 7, 2015 at 14:39

3 Answers 3

1

I'd say

awk -F, 'NR == 1 { split($0, headers); next } { for(i = 1; i <= NF; ++i) { print headers[i]; print $i } }' filename

That is

NR == 1 {                       # in the first line
  split($0, headers)            # remember the headers
  next                          # do nothing else
}
{                               # after that:
  for(i = 1; i <= NF; ++i) {    # for all fields:
    print headers[i]            # print the corresponding header
    print $i                    # followed by the field
  }
}

Addendum: Obligatory, crazy sed solution (not recommended for productive use; written for fun, not profit):

sed 's/$/,/; 1 { h; d; }; G; :a s/\([^,]*\),\([^\n]*\n\)\([^,]*\),\(.*\)/\2\4\n\3\n\1/; ta; s/^\n\n//' filename

That works as follows:

s/$/,/         # Add a comma to all lines for more convenient processing
1 { h; d; }    # first line: Just put it in the hold buffer
G              # all other lines: Append hold bufffer (header fields) to the
               # pattern space
:a             # jump label for looping

               # isolate the first fields from the data and header lines,
               # move them to the end of the pattern space
s/\([^,]*\),\([^\n]*\n\)\([^,]*\),\(.*\)/\2\4\n\3\n\1/
ta             # do this until we got them all
s/^\n\n//      # then remove the two newlines that are left as an artifact of
               # the algorithm.
Sign up to request clarification or add additional context in comments.

Comments

0

Here is one awk

awk -F, 'NR==1{for (i=1;i<=NF;i++) a[i]=$i;next} {for (i=1;i<=NF;i++) print a[i] RS $i}' file
Age
25
Name
Anand
Salary
32000

First for loop store the header in array a
Second for loop prints header from array a with corresponding data.

Comments

0

Using GNU awk 4.* for 2D arrays:

$ awk -F, '{a[NR][1];split($0,a[NR])} END{for (i=1;i<=NF;i++) for (j=1;j<=NR;j++) print a[j][i]}' file
Age
25
Name
Anand
Salary
32000

In general to transpose rows and columns:

$ cat file
11 12 13
21 22 23
31 32 33
41 42 43

with GNU awk:

$ awk '{a[NR][1];split($0,a[NR])} END{for (i=1;i<=NF;i++) for (j=1;j<=NR;j++) printf "%s%s", a[j][i], (j<NR?OFS:ORS)}' file
11 21 31 41
12 22 32 42
13 23 33 43

or with any awk:

$ awk '{for (i=1;i<=NF;i++) a[NR][i]=$i} END{for (i=1;i<=NF;i++) for (j=1;j<=NR;j++) printf "%s%s", a[j][i], (j<NR?OFS:ORS)}' file
11 21 31 41
12 22 32 42
13 23 33 43

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.