Input file is comma separated.
$ cat file.txt
hiddenhausen,99.60,y
herbstein,99.021,n
bangalore,98.82,y
golm,98.8,y
para,98.82,n
bogen,98.61,n
saintandre,98.5,n
delhi,98.61,y
hyderabad,99.02,y
Lets try to format the above file:
$ awk '{ printf "%-15s%-8s%s\n",$1,$2,$3}' FS=\, file.txt
hiddenhausen 99.60 y
herbstein 99.021 n
bangalore 98.82 y
golm 98.8 y
para 98.82 n
bogen 98.61 n
saintandre 98.5 n
delhi 98.61 y
hyderabad 99.02 y
So its printing first field ($1) as a string of 15 characters that are left-justified, 2nd field ($2) as 8 characters left-justified and then third field ($3)
With variable number of fields in each line, a generic solution would be:
$ awk '
{
for(i=1;i<=NF;i++)
printf("%-15s%c", $i, (i==NF) ? ORS : "")
}' FS=, file.txt
hiddenhausen 99.60 y
herbstein 99.021 n
bangalore 98.82 y
golm 98.8 y
para 98.82 n
bogen 98.61 n
saintandre 98.5 n
delhi 98.61 y
hyderabad 99.02 y
Related post:
-Formatting fields into columns in awk
5 comments:
Really nice one ...
Good use of built-in variables.
I usually do something like this.
awk '{ for(i=1;i<=NF;i++) printf("%-15s", $i); printf "\n"}'
@Mahesh, thanks for the same.
To make the methods table-driven, that is, need to re-run based on a
different delimiter for different input files, we needn't re-configure our
perl/sed codes. Just edit shell variable "sep" to the choice of delimiter.
sep=':'; # the data delimiter specified here
data='file.txt'; # file name containing data
# method-a)
< $data
sed -e '
1i\
.TS\
tab('"$sep"');\
l l n.
$a\
.TE
' | tbl - | nroff -Tascii -ms | grep '.'
# method-2)
perl \
-Mv5.10 \
-wMstrict \
-Mconstant" 'SEP','$sep'" \
-Mconstant'=COL_SPC,3' \
-Mvars='@lines,@maxw' \
-F"$sep" \
-lane '
push @lines, $_;
$a=-1;
++$a,length > ($maxw[$a]//0) and $maxw[$a] = length for@F}{
my $fmt = join q{}, map { "\%-" . ($_+COL_SPC) . "s" } @maxw;
print sprintf $fmt, split SEP, for @lines;
' < $data
Post a Comment