How to align printed elements in array?

F

Fred

I'm pushing 3 variables into an array named
@sorted_countries:

push(@invalid_countries, "$country_code\t$country\t$ip\n");

This is then sorted by country code:

@sorted_countries = sort @invalid_countries;

Now when I print @sorted_countries the output is
shifted, even though there is one tab between
each entry. I've tried increasing tabs, trimming
whitespace, among other things, and the output
is always shifted. Currently I'm playing with
the format/write commands. Any ideas how to
align the output?

-Thanks


CN China 202.108.23.70
CN China 202.160.180.105
CN China 202.160.180.169
CN China 202.160.180.213
CN China 218.18.32.21
CN China 220.189.253.74
CY Cyprus 82.211.152.11
DE Germany 213.196.210.186
IL Israel 147.234.2.4
IL Israel 84.94.114.250
IN India 203.196.158.244
IN India 59.93.73.113
IT Italy 80.21.203.2
PH Philippines 58.69.216.245
RU Russian Federation 81.19.66.8
RU Russian Federation 82.179.108.6
SA Saudi Arabia 212.138.64.171
SA Saudi Arabia 212.138.64.172
SA Saudi Arabia 212.138.64.173
SA Saudi Arabia 212.138.64.174
SA Saudi Arabia 212.138.64.176
TW Taiwan, Province of China 221.169.56.134
 
G

Gunnar Hjalmarsson

Fred said:
I'm pushing 3 variables into an array named
@sorted_countries:

push(@invalid_countries, "$country_code\t$country\t$ip\n");

This is then sorted by country code:

@sorted_countries = sort @invalid_countries;

Now when I print @sorted_countries the output is
shifted, even though there is one tab between
each entry. I've tried increasing tabs, trimming
whitespace, among other things, and the output
is always shifted.

for ( @sorted_countries ) {
printf '%-5s%-30s%s', split /\t/;
}

perldoc -f printf
perldoc -f sprintf
 
P

Paul Lalli

Fred said:
I'm pushing 3 variables into an array named
@sorted_countries:

No you're not.
push(@invalid_countries, "$country_code\t$country\t$ip\n");

You are pushing one string into @invalid_countries. Once you
interpolate those variables into a string, it is simply one
double-quoted string. No variables are stored in the array.
This is then sorted by country code:

No it's not.
@sorted_countries = sort @invalid_countries;

It's sorted by the string itself. There is no mechanism in the above
to sort only by the part of the string that came from the $country_code
variable.
Now when I print @sorted_countries the output is
shifted, even though there is one tab between
each entry. I've tried increasing tabs, trimming
whitespace, among other things, and the output
is always shifted.

I'm thinking you don't quite understand what a "tab" character actually
is.
Currently I'm playing with
the format/write commands. Any ideas how to
align the output?

perldoc -f sprintf

Do not create a pre-formated string in the array. Store the actual
variables, then sort on the actual value you want to sort on. Then
format your output as you're printing.

my @invalid_countries;
while (my ($country_code, $country, $ip) = get_info()){
push @invalid_countries, [$country_code, $country, $ip];
}

my @sorted_countries = sort { $a->[0] cmp $b->[0] } @invalid_countries;

for my $array_ref (@sorted_countries){
printf "%-2s %-25s %-15s\n", @$array_ref;
}

#I leave it to you to define get_info to retrieve the three values,
since
#you didn't show where they come from.

#The numbers above are based on the longest expected strings for the
#respective values. Adjust as necessary.

__END__

Paul Lalli

(Data remains below for reference sake)
 
D

David K. Wall

Fred said:
I'm pushing 3 variables into an array named
@sorted_countries:

push(@invalid_countries, "$country_code\t$country\t$ip\n");

This is then sorted by country code:

@sorted_countries = sort @invalid_countries;

Now when I print @sorted_countries the output is
shifted, even though there is one tab between
each entry. I've tried increasing tabs, trimming
whitespace, among other things, and the output
is always shifted. Currently I'm playing with
the format/write commands. Any ideas how to
align the output?

Yeah, I have an idea. Be (constructively) lazy and use Anno
Siegel's excellent Text::Table module.



use strict;
use warnings;
use Text::Table;

my @invalid_countries;
while (<DATA>) {
chomp;
push @invalid_countries, [ split /\s{2,}/, $_ ];
}
# see 'perldoc sort' if you're interested in more control over the
# sort algorithm used.
my @sorted_countries = sort { $a->[0] cmp $b->[0] } @invalid_countries;


my $table = Text::Table->new();

# if you want column headings use this next line instead
#my $table = Text::Table->new('Code', 'Country', 'IP');
$table->load( @sorted_countries );
print $table;


__DATA__
CN China 202.108.23.70
CN China 202.160.180.105
CN China 202.160.180.169
CN China 202.160.180.213
CN China 218.18.32.21
CN China 220.189.253.74
CY Cyprus 82.211.152.11
DE Germany 213.196.210.186
IL Israel 147.234.2.4
IL Israel 84.94.114.250
IN India 203.196.158.244
IN India 59.93.73.113
IT Italy 80.21.203.2
PH Philippines 58.69.216.245
RU Russian Federation 81.19.66.8
RU Russian Federation 82.179.108.6
SA Saudi Arabia 212.138.64.171
SA Saudi Arabia 212.138.64.172
SA Saudi Arabia 212.138.64.173
SA Saudi Arabia 212.138.64.174
SA Saudi Arabia 212.138.64.176
TW Taiwan, Province of China 221.169.56.134
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,503
Latest member
supremedee

Latest Threads

Top