Reputation: 947
I'm looking to convert a list containing days of the week with timings next to them, into a table like format.
Input below:
Mon 0100
Mon 0700
Tue 0700
Wen 0100
Wen 0700
Thu 0100
Thu 0700
Fri 0100
Fri 0700
Sat 0100
Sun 0100
Sun 0700
Ouput below:
Mon Tue Wed Thu Fri Sat Sun
0100 X X X X X X
0700 X X X X X X
Looking for answers in awk ideally. Preservation of format in the output given is preferred. In the scenario whereby a weekday does not exist, it should not be included (If possible it would be nice to also have the answer which would include the missing weekday in the output, if it does not exist in the input).
I gave this a shot, but aside from printing the first row, I really can't get my head around the construct of the arrays, even though I imagine it is relatively simple.
Thanks Ell
Upvotes: 2
Views: 116
Reputation: 77105
Here is one way using awk
:
awk '
!($1 in day) { days[++d] = $1; day[$1]++ }
!($2 in num) { nums[++n] = $2; num[$2]++ }
{ map[$1,$2]++ }
END {
printf "\t"
for (i=1; i<=d; i++) {
printf "\t%s", days[i]
}
print ""
for (j=1; j<=n; j++) {
printf "%s ", nums[j]
for (i=1; i<=d; i++) {
printf "\t%s", (map[days[i],nums[j]] ? "X" : FS )
}
print ""
}
}' file
Mon Tue Wen Thu Fri Sat Sun
0100 X X X X X X
0700 X X X X X X
Upvotes: 5
Reputation: 120644
I'm sure there is a much more elegant solution (I don't really know awk - just going by the gawk manual):
BEGIN {
days["Mon"] = 1
days["Tue"] = 2
days["Wen"] = 4
days["Thu"] = 8
days["Fri"] = 16
days["Sat"] = 32
days["Sun"] = 64
}
{
hours[$2] = or(hours[$2], days[$1])
}
END {
print " Mon Tue Wed Thu Fri Sat Sun"
for (key in hours) {
printf "%s ", key
for (i = 0; i < 7; i++) {
if (and(hours[key], 2 ** i))
printf "X"
else
printf " "
printf " "
}
print ""
}
}
Note that in your sample input file, Wednesday is "Wen" but in your output it is "Wed." If the sample input file has a typo on your part, you will need to change line 4 of the script above to match.
Upvotes: 1