Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a dataset as such:

Name:      Jim Bean
Vice:      Dice
ID:        AFDSDFDSFDSFASFA
LoginTime: 12343314

Name:      Bob Dylon
Vice:      Trumpets
ID:        AFD232SFDSFASFA
LoginTime: 12343314

Name:      Mary Jane
Vice:      Gambling
ID:        EWDSFDSFASFA
LoginTime: 12343314

.....

I need to arrange this into a columnar format. My first thought is to use awk. But I'm a bit stuck.

The labels will always appear in the same order, also it will always show the same number of label/value pairs in each group (headers aren't important).

My question is: How would I do this?

I've seen hints that the command rs may be able to do something like that, but its not standard on all systems.

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

You should post desired output with your question. My guess was this:

$ awk '{ if($2) printf("%s ", $2); else print ""; }' < dataset
Jim Dice AFDSDFDSFDSFASFA 12343314 
Bob Trumpets AFD232SFDSFASFA 12343314 
Mary Gambling EWDSFDSFASFA 12343314

Note that this is an awfully stupid method, it does not validate anything at all. If your input looks any different from what you posted it will probably break.

share|improve this answer
    
You're right... I'm going to update this question to include last names in the names... which will make this fail. Is there a way to make this quote the values? –  monksy Feb 7 '13 at 23:52
    
Silly me just add in: " $1=""; printf("%s ", $0); " and I'll accept the answer –  monksy Feb 7 '13 at 23:56
    
Are you sure? If you have spaces in your fields, using space as column separator you won't be able to tell where one column ends and the next one starts. Maybe you want tab or zero as separator? Your question unfortunately leaves much to interpretation, hence you're getting weird answers such as mine. –  frostschutz Feb 8 '13 at 2:35
    
You're right about that. Thor's answer does look tempting. Although I did upvote you. –  monksy Feb 8 '13 at 6:32
add comment

You can do it like this with GNU awk, note the use of RS and FS:

<infile awk '{ print $2, $4, $6, $8 }' RS='\n\n' FS=': +|\n' OFS='\t'

If you want to keep the header:

<infile awk 'NR==1 { print $1, $3, $5, $7 } { print $2, $4, $6, $8 }' RS='\n\n' FS=': +|\n' OFS='\t'

Assuming all your records are formatted like this, you could do it like this with coreutils:

<infile grep -v '^$' | tr -s ' ' | cut -d' ' -f2- | paste - - - -

Output:

Jim Bean    Dice    AFDSDFDSFDSFASFA    12343314
Bob Dylon   Trumpets    AFD232SFDSFASFA 12343314
Mary Jane   Gambling    EWDSFDSFASFA    12343314

Output with header:

Name    Vice    ID      LoginTime
Jim Bean        Dice    AFDSDFDSFDSFASFA        12343314
Bob Dylon       Trumpets        AFD232SFDSFASFA 12343314
Mary Jane       Gambling        EWDSFDSFASFA    12343314
share|improve this answer
    
Nice, +1. What exactly is the field separator? Is it (: followed by one or more spaces) OR (newline)? –  terdon Feb 8 '13 at 2:05
    
@terdon: it's actually both, as you may notice $1 refers to the first label, and $2 refers to its value, $3refers to the second label $4to $3's value etc. –  Thor Feb 8 '13 at 2:23
    
Yes, that's what I meant by OR. Brilliant, I did not know I could give multiple FSs to gawk. –  terdon Feb 8 '13 at 2:48
    
I'm not sure what it was but the $2 ... with the even numbers miss parsed some of the fields and it threw off everything. –  monksy Feb 8 '13 at 20:30
    
@monksy: is the input tab-delimited? in that case use FS=':[\t ]*|\n'. –  Thor Feb 8 '13 at 22:15
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.