Data Not Ok 100 123 1.......1 Data Ok 100 123 1.........1 #### use strict; use warnings; my @row; while(my $line = ) { my @arr; while(my ($elem) = $line =~ /(\s*\d+)/g) { push @arr, $elem; $line =~ s/(\s*$elem)/' ' x length($1)/e; } #Data 1014 1 10 #becomes 3 element "1014", " 1", " 10" push @row, \@arr; } #Sort element with same length, exchange position foreach my $r1 (0 .. $#row) { #Take 1 row as base, check other rows my @remain = grep !/$r1/,(0 .. $#row); foreach my $r2 (0..$#remain) { #Foreach element in row, find element with same length #in different row (mean same column) -> check value and exchange foreach my $c1 (0..$#{$row[$r1]}) { foreach my $c2 (0..$#{$row[$r2]}) { compare_wrap($row[$r1][$c1], $row[$r2][$c2]); } } } } map {print merge_str(@$_),"\n"} @row; #SUPPORT FUNCTION sub compare_wrap { if( length($_[0]) == length($_[1]) && eval($_[0]) < eval($_[1])) { @_[0, 1] = @_[1, 0]; } } sub merge_str { foreach my $i (1 .. $#_) { my $temp = ' ' x length($_[$i-1]); $_[$i] =~ s/$temp/$_[$i-1]/; } $_[-1]; } __DATA__ 1014 1 10 1015 51 100 20 1016 11 101 1017 15 101