Reputation: 1
I'm aware that there are a lot of similar questions but I can't find an answer that relates to my particular use case, though I'll admit that this may be due to my lack of understanding more than anything else.
I am currently using the following format to print the contents of a csv file:
awk -F, 'BEGIN{printf "%-10s %-10s %-5s %-20s\n", "Col1","Col2,"Col3","Col4"} {printf "%-10s %-10s %-5s %-20s\n",$1,$2,$3,$4} test.csv
Instead of the columns being 10, 10, 5 and 20 I want them to use the variables $col1length, $col2length and so on. So if $col1length is 20 characters long then the width will format to being 20 characters wide. I'm new to this so I'm struggling to use answers from similar questions and change them to match my use case without breaking the command completely.
Edit: I'm not sure what else to add to address Ed Mortons request. My csv file contains data like the following:
longtextstring,databasename1,12345,2022-05-10T11:35:01.000Z
evenlongertextstring,databasename2,1234567,2022-05-10T11:21:02.000Z
shrtstring,db3,987,2022-05-10T10:15:11.000Z
anotheryveryveryverylongtextstring,dbname3,483,2022-04-17T01:45:09.000Z
I can get the length of the longest field in each column and have those saved to the variables named col1length to col2length. So I know that the length of the longest string in col1 is 34 characters.
Using the code above I can output with fixed width columns but I want to use the variables mentioned to dynamically change the column widths every time the code is run. I've attempted to solve the problem myself to no avail, this is why I am posting the question. I've tried to read similar questions and interpret those answers to solve my own issue but those attempts have resulted in errors such as:
$ awk -F, 'BEGIN{printf "%-$s*s %-10s %-5s %-20s\n", "Col1","Col2,"Col3","Col4"} {printf "%-$s*s %-10s %-5s %-20s\n",$1,$2,$3,$4} test.csv
ask: cmd. lin:1: fatal: not enough arguments to satisfy format string
`%-*s %-10s %-5s %-20s
^ran out for this one
When I try to replace the number with the variable I get the error:
$ awk -F, 'BEGIN{printf "%-$col1lengths %-10s %-5s %-20s\n", "Col1","Col2,"Col3","Col4"} {printf "%-$col1lengths %-10s %-5s %-20s\n",$1,$2,$3,$4} test.csv
awk: cmd. lin:1: fatal: arg count with `$' must be > 0
Upvotes: 0
Views: 505
Reputation: 204064
The correct syntax to do what you were trying to do with your printf
lines is either:
$ awk 'BEGIN{col1lengths=17; printf "%-*s %-5s\n", col1lengths, "Col1", "Col2"}'
Col1 Col2
or if you prefer:
$ awk 'BEGIN{col1lengths=17; printf "%-"col1lengths"s %-5s\n", "Col1", "Col2"}'
Col1 Col2
You didn't show the expected output yet so it's a guess but maybe this is what you're trying to do over all:
$ cat tst.awk
BEGIN {
ARGV[ARGC++] = ARGV[1]
FS=","
}
NR == FNR {
for ( i=1; i<=NF; i++ ) {
wid = length($i)
wids[i] = (wid > wids[i] ? wid : wids[i])
}
next
}
FNR == 1 {
for ( i=1; i<=NF; i++ ) {
hdr = "Col" i
wid = length(hdr)
wids[i] = (wid > wids[i] ? wid : wids[i])
printf "%-*s%s", wids[i], hdr, (i<NF ? OFS : ORS)
}
}
{
for ( i=1; i<=NF; i++ ) {
printf "%-*s%s", wids[i], $i, (i<NF ? OFS : ORS)
}
}
$ awk -f tst.awk test.csv
Col1 Col2 Col3 Col4
longtextstring databasename1 12345 2022-05-10T11:35:01.000Z
evenlongertextstring databasename2 1234567 2022-05-10T11:21:02.000Z
shrtstring db3 987 2022-05-10T10:15:11.000Z
anotheryveryveryverylongtextstring dbname3 483 2022-04-17T01:45:09.000Z
but you may want to consider using column
instead of having awk
calculate the column widths:
$ awk -F',' 'NR==1{for (i=1;i<=NF;i++) printf "Col"i (i<NF?FS:ORS)} 1' test.csv |
column -s',' -o' ' -t
Col1 Col2 Col3 Col4
longtextstring databasename1 12345 2022-05-10T11:35:01.000Z
evenlongertextstring databasename2 1234567 2022-05-10T11:21:02.000Z
shrtstring db3 987 2022-05-10T10:15:11.000Z
anotheryveryveryverylongtextstring dbname3 483 2022-04-17T01:45:09.000Z
Upvotes: 1