1

I have file something like this,

SR   Name               Rollno   Class

1    Sanjay              01       B
2    Rahul_Kumar_Khanna  09       A

Now I need to add "|" between each. So it should look like

SR | Name              |Rollno | Class|

1  | Sanjay            |01     | B    |
2  | Rahul_Kumar_Khanna|09     | A    |

I am using Perl6::form

my $text;
        
foreach my $line (@arr) {
    my ($SR, $Name, $Rollno, $Class) = split (" ", $line);
    my $len = length $Name;
    $text = form 
        '| {||||||||} | {||||||||} | {||||||||} | {||||||||}|', 
            $SR,         $Name,       $Rollno,     $Class;
    print $text;
}

Here till now I have done but the name is not comming out properly. I have add extra "|" in name for that. Is there any way we can add "|" by calculating length like(below). I tried but getting error.

'| {||||||||} | {||||||||}x$len | {||||||||} | {||||||||}|',
ikegami
  • 367,544
  • 15
  • 269
  • 518
Alexx
  • 475
  • 2
  • 8
  • 1
    How do you know that "Rahul Kumar" is one field (and not two fields) ? If you split on space (as you do) it will become two fields.. – Håkon Hægland Sep 22 '20 at 08:29
  • @HåkonHægland Ok now check. Now It will come in one field. My problem is if in future I need add other name which are bigger then the existing names then for that I have to put extra "|" so that name won't get cut. – Alexx Sep 22 '20 at 08:35
  • @HG: _name which are bigger then the existing names_ If the bigger name is space separated, then the logic (`split (" ", $line)`) would not work as per the expectation I believe. – vkk05 Sep 22 '20 at 08:39
  • @vkk05 I tried with the bigger names compare to "Rahul_Kumar_Khanna" , but the problem I am facing is I need to increase the "|" of 2nd column so that full name comes without getting cut. Split is working fine . – Alexx Sep 22 '20 at 08:49
  • 2
    @HG You could scan the file first as a preprocessing step to find the maximum length of the name field, then loop through the lines again using the maximum length to format the name field.. – Håkon Hægland Sep 22 '20 at 09:04

1 Answers1

2

Problem #1

'| {||||||||} | {||||||||}x$len | {||||||||} | {||||||||}|'

produces

| {||||||||} | {||||||||}x20 | {||||||||} | {||||||||}|

but you're trying to get

| {||||||||} | {||||||||||||||||||||} | {||||||||} | {||||||||}|

For that, you'd want

'| {||||||||} | {'.( "|" x $len ).'} | {||||||||} | {||||||||}|'

Problem #2

$len is the length of the name field of the current row. It's different for every row. This is wrong, cause you want the output to be the same width for every row. $len needs to be the length of the longest name field.

You will need to find the correct value for $len before even starting the loop.

# Read in the data as an array of rows.
# Each row is an array of values. 
my @rows = map { [ split ] } <>;

# Find the maximum width of each column. 
my @col_lens = (0) x @{rows[0]};
for my $row (@rows) {
   # Skip the blank line after the header. 
   next if !@$row;

   for my $col_idx (0..$#$row) {
      my $col_len = $row->[$col_idx];
      if ($col_lens->[$col_idx] < $col_len) {
         $col_lens->[$col_idx] = $col_len;
      }
   }
}

my $form =
   join "",
      "| ",
      "{".( "|"x($col_lens[0]-2) )."}",
      " | ",
      "{".( "|"x($col_lens[1]-2) )."}",
      " | ",
      "{".( "|"x($col_lens[2]-2) )."}",
      " | ",
      "{".( "|"x($col_lens[3]-2) )."}",
      " |";

for my $row (@rows) {
   if (@$row) {
      print form($form, @$row);
   } else {
      print "\n";
   }
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 1
    Forgot to mention you could create a `sprintf` pattern using the same approach – ikegami Sep 23 '20 at 19:15
  • Can you explain the problem #2? or add comments in the code ? Thankyou. – Alexx Sep 28 '20 at 04:55
  • Well, you need the maximum width of the name column, so it finds that. Actually, it gets the maximum width of every column. Comments added. – ikegami Sep 28 '20 at 07:13
  • Can you check this question [https://stackoverflow.com/questions/64121838/why-after-the-while-loop-i-am-only-getting-last-row-value?noredirect=1#comment113392167_64121838] – Alexx Sep 29 '20 at 16:25