Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Andrzejek on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Make a table from a list

Status
Not open for further replies.

GreenHen

Technical User
May 30, 2014
2
IE
Awk newbie:
My input file gathers data as a list:

timestamp1
type1 a
type1 b
type1 c
type2 d
type2 e
type4 g
type5 h
type5 i
type5 j
type5 k
type5 l
timestamp2
type2 d
type2 e
type3 a
type3 b
type3 c
type4 g
type5 h
type5 i
type5 j
type5 k
type5 l
timestamp3
type2 d
type2 e
type3 a
type3 b
type3 c
type4 g
type4 h
type4 i
type6 j
type6 k
type6 l

I need to reformat as a table:

timestamp1 type1 a b c
timestamp1 type2 d e
timestamp1 type3
timestamp1 type4 g
timestamp1 type5 h i j k l
timestamp1 type6

timestamp2 type1
timestamp2 type2 d e
timestamp2 type3 a b c
timestamp2 type4 g
timestamp2 type5 h i j k l
timestamp2 type6

timestamp3 type1
timestamp3 type2 d e
timestamp3 type3 a b c
timestamp3 type4 g h i
timestamp3 type5
timestamp3 type6 j k l

There is a defined range of types. The number of entries for each type varies in each time interval. Timestamp does not follow a regular interval.
 
What have you tried so far and where in your code are you stuck ?

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Here is my best (clumsy) attempt to date:

First step (not awk!) I sort all the types by time using

>for i in type1 type2 type3 type4 type5 type6
>do
>grep -e time -e type source_text >> source_text_sorted
>done

This gives me source_text_sorted:
timestamp1
type1 a
type1 b
type1 c
timestamp1
type2 d
type2 e
timestamp1
type4 g
timestamp1
type5 h
type5 i
type5 j
type5 k
type5 l

etc.

Now I use time as a record separator and newline as a field separator to reformat the list
>awk 'BEGIN { RS = "timestamp"; FS = "\n" }; {print $1, $2, $3, $4, $5}' source_text_sorted

(I should say that I have a 'flag' on timestamp that identifies it as a timestamp)

This gives me:
1 type1 a type1 b type1 c
1 type2 d type2 e
1 type4 g
1 type5 h type5 i type5 j type5 k

etc.

Now I use sed to 'clean up', removing all the extra types in each line:

sed 's/type/first_type/'
sed 's/ type//g'

My main problem with this method (apart from the lack of elegance) is that I can't be sure how many fields are in a record. If I am explicit with the number of fields in my awk print, I run the risk of leaving out fields from a longer than anticipated record. Is there a way to define a range of fields e.g. $1 to $NF ? I have tried {print $0} but this retains the original record format.
 


Try this:
Code:
==> cat kk
awk '
function printout(){
  for(k in O){print ts,k,O[k]; delete Oi[k]}
}
/^timestamp/{
  if(i>0){printout()}
  ts=$1; T[++i]=ts;
  next
}
{O[$1]=O[$1]" "$2}
END {printout()
}' infile

==> ./kk|sort
timestamp1 type1  a b c
timestamp1 type2  d e
timestamp1 type4  g
timestamp1 type5  h i j k l
timestamp2 type1  a b c
timestamp2 type2  d e d e
timestamp2 type3  a b c
timestamp2 type4  g g
timestamp2 type5  h i j k l h i j k l
timestamp3 type1  a b c
timestamp3 type2  d e d e d e
timestamp3 type3  a b c a b c
timestamp3 type4  g g g h i
timestamp3 type5  h i j k l h i j k l
timestamp3 type6  j k l
==>
[3eyes]


----------------------------------------------------------------------------
The person who says it can't be done should not interrupt the person doing it. -- Chinese proverb
 
Oooops script had bug...
Here:
Code:
==> cat kk
awk '
function printout(){
  for(k in O){print ts,k,O[k]; delete O[k]}
}
/^timestamp/{
  if(i>0){printout()}
  ts=$1; T[++i]=ts;
  next
}
{O[$1]=O[$1]" "$2}
END {printout()
}' infile

==> ./kk|sort
timestamp1 type1  a b c
timestamp1 type2  d e
timestamp1 type4  g
timestamp1 type5  h i j k l
timestamp2 type2  d e
timestamp2 type3  a b c
timestamp2 type4  g
timestamp2 type5  h i j k l
timestamp3 type2  d e
timestamp3 type3  a b c
timestamp3 type4  g h i
timestamp3 type6  j k l
[noevil]


----------------------------------------------------------------------------
The person who says it can't be done should not interrupt the person doing it. -- Chinese proverb
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top