Help! output format from vertical to horizontal

Hi All,

please help to achieve the desired output
Example: I have a file which contains the below data

empname
robert
empid
787
design
consultant
empname
alex
empid
898
design
advocate

Desired output should be

empname empid design
robert 787 consultant
alex 898 advocate

I have achieved the below output with the command but this is not my requirement.

 paste -d '  '  - - < inputfile > outputfile
empname robert
empid 787
design consultant
empname alex
empid 898
design advocate

Kindly help me to achieve the desired output as shown above

Thanks in advance.

xargs -n6 < file | awk '
        NR == 1 {
                for ( i = 1; i <= NF; i+=2 )
                        printf "%s\t", $i
                printf "\n"
        }
        {
                for ( i = 2; i <= NF; i+=2 )
                        printf "%s\t", $i
                printf "\n"
        }
'

Simple approach

awk 'BEGIN {print "empname empid design"} /empname/ {getline;printf "%s ",$0;getline;getline;printf "%s ",$0;getline;getline;print}'

Thanks a lot Jotne and Yoda for excellent commands.

Some more variation

awk 'BEGIN {print "empname empid design"} /empname/{a=NR} NR==a+1||NR==a+3{printf "%s ",$0} NR==a+5' file

Could you please let me know why at the last

 printf 

is not used here? Also is this

 %s 

is used for formatting?

Will be grateful to you for same.

Thanks,
R. Singh

The GNU Awk User's Guide: Printing

Another way:

$ awk '!(NR%2){printf $1" ";c++}c==3{c=0;printf "\n"}' data
robert 787 consultant 
alex 898 advocate 

Jotne, Yoda and Ravinder

Thanks a lot for your help.

Still, am unable to achieve the desired output as per my requirement.
I have a file which has more than 1000 lines of data and the format is similar to the sample one provided in this thread.

Q:
What if there are more than 1000 employess list in a file.
How could we achieve to get the desired output through iterating till end of the file.

Thanks in advance.

As long as the format of the file is constant this should be no problem to solve.
All this example runs to end of file and prints new line for every employ.
Can you post more real data, like 30-40 lines, it would help us to help you.

Below is the real data from which I want to generate the required output.
I have just given a first two cases it has totally more than 1000 lines of similar data and ofcourse the values will be different ( header remains the same "name, svc, isCached, isPrefetched, sAccessLast, sAccessTotal and sRunning ")

I feel if it works for below then obviously it will work for entire file the only case is to iterate through entire file.

name
COM.WM.ISEXTDC.PKGINIT:INIT
svc
init
isCached
N
isPrefetched
N
sAccessLast
2013-07-13 00:39:10 MEST
sAccessTotal
1
sRunning
5
name
DSM_APPS_MANAGEMENT.BROKERCLIENTQUEUE_CLEANUP:CLEANUP
svc
cleanup
isCached
N
isPrefetched
N
sAccessLast
2013-08-03 16:14:19 MEST
sAccessTotal
1041
sRunning
1

Thanks for your time and support

Well, this is a special case, and I don't know if this will work on your long file. I have to cling to some assumptions, e.g. that every record has and starts with a name. Anyhow, give this a shot:

paste -d " " - - <file |
awk     'NR>1 && $1=="name"     {if (!HdFull) for (i=1; i<=c; i++) printf "%s\t", Hd; print ""
                                 for (i=1; i<=c; i++) printf "%s\t", Dt[Hd]; print ""
                                 delete Dt; HdFull = 1 } 
         !HdFull                {Hd[++c] = $1}
                                {Dt[$1]  = $2}
         END                    {for (i=1; i<=c; i++) printf "%s\t", Dt[Hd];  print ""}
        ' file
name    svc    isCached    isPrefetched    sAccessLast    sAccessTotal    sRunning    
COM.WM.ISEXTDC.PKGINIT:INIT    init    N    N    2013-07-13    1    5    
DSM_APPS_MANAGEMENT.BROKERCLIENTQUEUE_CLEANUP:CLEANUP    cleanup    N    N    2013-08-03    1041    1    

I'm sure your intentions were good, but, in the future, don't dumb down the data. Instead of simplifying matters, it usually complicates them and wastes everyone's time.

Here's an approach not too far from your original attempt. For flexibility, the number of fields per record is parameterized, n . It's simpler than any functionally-equivalent single AWK script will be, though not as efficient. However, unless you will be executing it repeatedly in a tight loop, or unless the dataset is massive (tens of thousands of lines is not massive), on typical hardware the pipeline's overhead is of no concern.

 n=7    # Fields per record
{ awk 'NR==n*2 {exit} NR%2' n=$n file; awk '!(NR%2)' file; } | paste -d ' ' $(yes - | head -n $n)

Regards,
Alister

Try this...

awk ' !f{ff=$0; f=1} !x && NR%2 { if(!(f>1 && $0 ~ ff)){printf "%s\t", $0} if(f==1){f++;next}}
!(NR%2) { d=d" "$0 } $0 ~ ff {print "\n"d; x=1;d=""} END{print d} ' input_file

--ahamed

Alister - Executed the givne code, below is the output

awk ' !f{ff=$0; f=1} !x && NR%2 { if(!(f>1 && $0 ~ ff)){printf "%s\t", $0} if(f==1){f++;next}}
!(NR%2) { d=d" "$0 } $0 ~ ff {print "\n"d; x=1;d=""} END{print d} ' < $TEMP/$SCRIPT.emp > $TEMP/$SCRIPT.out8
output: 
awk: syntax error near line 1
awk: bailing out near line 1

2) Rudic - Executed the code given, below is the output
Output:

awk: syntax error near line 4
awk: bailing out near line 4

3) Ahamed,

awk ' !f{ff=$0; f=1} !x && NR%2 { if(!(f>1 && $0 ~ ff)){printf "%s\t", $0} if(f==1){f++;next}}
!(NR%2) { d=d" "$0 } $0 ~ ff {print "\n"d; x=1;d=""} END{print d} ' < $TEMP/$SCRIPT.emp 
output :
awk: syntax error near line 1
awk: bailing out near line 1

kinldy help.

Please use code tags...

On Solaris, use nawk or /usr/xpg4/bin/awk

1 Like

That's not my code.

Mine works fine with your most recent data.

$ n=7 file=data

$ { awk 'NR==n*2 {exit} NR%2' n=$n "$file"; awk '!(NR%2)' "$file"; } | paste -d ' ' $(yes - | head -n $n)
name svc isCached isPrefetched sAccessLast sAccessTotal sRunning
COM.WM.ISEXTDC.PKGINIT:INIT init N N 2013-07-13 00:39:10 MEST 1 5
DSM_APPS_MANAGEMENT.BROKERCLIENTQUEUE_CLEANUP:CLEANUP cleanup N N 2013-08-03 16:14:19 MEST 1041 1

$ cat "$file"
name
COM.WM.ISEXTDC.PKGINIT:INIT
svc
init
isCached
N
isPrefetched
N
sAccessLast
2013-07-13 00:39:10 MEST
sAccessTotal
1
sRunning
5
name
DSM_APPS_MANAGEMENT.BROKERCLIENTQUEUE_CLEANUP:CLEANUP
svc
cleanup
isCached
N
isPrefetched
N
sAccessLast
2013-08-03 16:14:19 MEST
sAccessTotal
1041
sRunning
1

Regards,
Alister

Scott - It worked for me

Alister - Am just checking what's wrong with the given code am unable to locate where the problem lies.

file=data
n=7
{ awk 'NR==n*2 {exit} NR%2' n=$n "$file"; awk '!(NR%2)' $file; } | paste -d ' ' $(yes - | head -n $n)
cat "$file"

Output:

awk: syntax error near line 1
awk: bailing out near line 1
awk: syntax error near line 1
awk: bailing out near line 1
name
COM.WM.ISEXTDC.PKGINIT:INIT
svc
init
isCached
N
isPrefetched
N
sAccessLast
2013-07-13 00:39:10 MEST
sAccessTotal
1
sRunning
5
name
DSM_APPS_MANAGEMENT.BROKERCLIENTQUEUE_CLEANUP:CLEANUP
svc
cleanup
isCached
N
isPrefetched
N
sAccessLast
2013-08-03 16:14:19 MEST
sAccessTotal
1041
sRunning
1

Hi, Jotne, RudiC & alister
Am sorry for re-opening this thread again.
Am in need of your help to get the desired output.

name
SECURITY.SERVICES.CONFIG:GETVALUE
isPrefetched
N
sAccessLast
2013-09-13 10:50:13 MEST
sAccessTotal
1
sRunning
cHitLast
name
PUBLIC.SERVER:INVOKE
isPrefetched
N
sAccessLast
2013-09-17 15:02:05 MEST
sAccessTotal
713991
sRunning
1
name
PUBLIC.STRING:CONVERTTOSTRING
isPrefetched
N
sAccessLast
2013-09-17 03:01:54 MEST
sAccessTotal
961
sRunning
cHitLast

1) I have data which has more thand 10,000 lines with the above same pattern.
2) I was checking the value of parameter 'sRunning' which should be a numerical value ( i.e, greater than 0 )
3) Here in the above live data the parameter(sRunning) is 'cHitLast and in the second case it is 1
4) I need to print the above 4 + 1(including sRunning ) values whereever the sRunning has a value greater than 0 ( zero) example shown below
5) Need to ignore if the value of sRunning which is other than numerical.
For the above code the output should be as below

name     isPrefetched   sAccessLast      sAccessTotal  sRunning
PUBLIC.SERVER:INVOKE  N       2013-09-17 15:02:05 MEST                    713991 1

This was code given by jote and it worked for some part but latter am not able to get the desired output.

nawk ' !f{ff=$0; f=1} !x && NR%2 { if(!(f>1 && $0 ~ ff)){printf "%s\t" "\t", $0} if(f==1){f++;next}}
  !(NR%2) { d=d" "$0 } $0 ~ ff {print "\n"d; x=1;d=""} END{print d} '

Thanks a lot for your support.

Hi.

Comments:

1) The post # 19 although seeming to be similar is really a different topic. If so, then it should be in a different (new) thread. That may be why there have been no responses for 2 days.

2) I strongly agree with alister in post 13 about posted data needing to be a representative sample, and not some simplified form.

3) For the question on general, the utility pr can generally handle such tasks. For example, given that the data would be on a file data1, the command on Debian GNU/Linux 5.0.8 (lenny) :

pr -3 -l2 -T -s" " data1

produces

empname empid design
robert 787 consultant
empname empid design
alex 898 advocate

The idea being that columns can be specified as well as the length of a page (in this case 2 lines, no titles, no headers, no footers). See man pr for details.

Best wishes ... cheers, drl