I have a file as below
Input File:
5/11/2012, dir1, 134
5/11/2012, dir2, 2341
5/11/2012, dir3, 2134
5/11/2012, dir4, 2334
5/12/2012, dir1, 234
5/12/2012, dir2, 2341
5/12/2012, dir3, 2334
5/13/2012, dir1, 234
5/13/2012, dir2, 2341
5/13/2012, dir3, 2334
5/13/2012, dir4, 21134
Now I am looking for a output using awk
Expected output:
Date dir1 dir2 dir3 dir4
5/11/2012 134 2341 2134 2334
5/12/2012 234 2341 234 -
5/13/2012 234 2341 2334 21134
Now I trying to write in awk ; taking details in array and trying to make a file but not successful
Problem in here is I need to have two group by one on date another on Directory
Could this help you ?
sort -t"," -k1,2 file1.txt -o file1.txt
OR
sort -t"," -k1,2 file1.txt > file2.txt; mv file2.txt file1.txt
awk -F"," 'NR==FNR{a[$2"|"$1]=$3;b[$2]++;next}
{if(FNR==1){printf "Date\t|";for(i in b){printf i"|";c[++k]=i}printf "\n";} for(j=1;j<=k;j++){if(c[j]==$2 && x!=$1) {printf "\n"$1"|"$3"|";x=$1;next}else if(c[j]!=$2 && x!=$1){printf "\n"$1"||";x=$1;}else if (c[j]==$2 && x==$1){printf "|"$3;x=$1;next}else if (c[j]!=$2 && x==$1){x=$1}else {x=$1;}} }END{printf "\n";}' file1.txt file1.txt
Thanks Pravin but I have only one file with the data and other part is output. I updated it with input file and output file.
---------- Post updated at 03:30 AM ---------- Previous update was at 03:18 AM ----------
I am doing something like
for dir in `awk -F, '{ print $2 }' data | sort | uniq`
do
echo -en "$dir"
for dt in `grep " $dir " data | awk -F, '{ print $1 }' | sort | uniq `;
do
val=`grep "$dir " data | grep $dt | awk -F, '{ print $3 }'`
echo -en "\t\t$val"
done
echo -e "."
done
which is not working anyways. Also looking if any one has cleaner solution.
#!/bin/bash
echo -e "\t\tDATE\tDIR1\tDIR2\tDIR3\tDIR4\n"
for date in `awk -F, '{ print $1 }' file | sort | uniq`
do
printf "%20s" $date
for dir in `awk -F, '{ print $2 }' file | sort | uniq `;
do
val=`grep -E "$date.*$dir" file | awk -F, '{ print $3 }'`
printf "%8d" $val
done
echo -e "\n"
done
In awk, (pseudo code)
If $2 = dir1 then print $1,\t,$3 without a new line.
Else print \t,$3.
If $2=dir4 then print \n
OK
Hi ,
try this:
#!/bin/bash
h=0
declare -a str_h
declare -a str_v
res=""
old_str_d=""
for head in $(cat $1 |cut -d"," -f2|sort |uniq )
do
str_h[$h]=$head
let h=h+1
done
echo -en "day\t"
for a in "${str_h[@]}"
do
echo -en "\t\t$a"
done
echo ""
(cat $1;echo 99999999)|sort -k1,3 |while read values
do
str_date=$(echo $values|cut -d"," -f1|sed 's/ *//g')
if [ "$str_date" == "99999999" ]
then
echo -n $old_str_d
c=0
while [ $c -lt "${#str_v[@]}" ]
do
echo -en "\t\t${str_v[$c]}"
str_v[$c]=""
let c=$c+1
done
echo ""
exit
fi
if [ "$str_date" != "$old_str_d" ]
then
echo -n $old_str_d
c=0
while [ $c -lt "${#str_v[@]}" ]
do
echo -en "\t\t${str_v[$c]}"
str_v[$c]=""
let c=$c+1
done
echo ""
str=""
old_str_d=$str_date
fi
if [ "$str_date" == "$old_str_d" ]
then
dir=$(echo $values|cut -d"," -f3|sed 's/ *//g')
c=0
str_tmp=""
for a in "${str_h[@]}"
do
if [ "$(echo $values|grep $a)" != "" ]
then
str_v[$c]="$dir"
fi
let c=$c+1
done
fi
done
#!/bin/bash
column -t infile | sort -t"," -k1,2 | \
awk -F'[, ]+' '
BEGIN {print "date dir1 dir2 dir3 dir4"}
{
a[$1]=a[$1]OFS$3
}
END {
for(i in a) print i,a
}' | awk '$5=$5<0?"-":$NF' | column -t