2

Using Perl, I just want to substitute the space to 0. Spaces were separated by tab (\t). Thanks in advance! For example:

1   2           2       5               4
4   4   4           4               3   
        4   4           1               
    1   5   6       4                   

To

1    2    0    0    2    0    5    0    0    0    4
4    4    4    0    0    4    0    0    0    3    0
0    0    4    4    0    0    1    0    0    0    0
0    1    5    6    0    4    0    0    0    0    0

My code:

use strict;
use warnings;
open(DATA,"DATA")||die"cannot open the file: $!\n";


while( <DATA> )
  {
  s/(^|    \K)(?!\d)/0/g;
  print;
  }

It comes out:

1   2           2       5               4
4   4   4           4               3   
0       4   4           1               
0   1   5   6       4                   
ikegami
  • 367,544
  • 15
  • 269
  • 518
yueli
  • 43
  • 7

2 Answers2

2
use strict;
use warnings qw( all );
use feature qw( say );

while (<>) {
   chomp;
   my @fields = split(/\t/, $_, -1);
   for my $field (@fields) {
      $field = 0 if $field eq "";
   }

   say join "\t", @fields;
}

It's not clear what you meant by "the space". The above replaces empty fields with zero. Chose the most suitable of the following:

  • if $field eq "" (empty)
  • if $field eq " " (1 space)
  • if $field =~ /^[ ]+\z/ (1+ spaces)
  • if $field =~ /^[ ]*\z/ (0+ spaces)
  • if $field =~ /^\s+\z/ (1+ whitespace)
  • if $field =~ /^\s*\z/ (0+ whitespace)
Gerhard
  • 22,678
  • 7
  • 27
  • 43
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Hello, ikegami, Thank you so much for your great help. It works! – yueli Aug 17 '18 at 20:33
  • Added a missing `chomp`. – ikegami Aug 17 '18 at 20:37
  • Hello, ikegami. I can read through your code. May I ask you a quick question? Why there is "-1" in split (/\t/,$_,-1)?Thanks again for your help! – yueli Aug 17 '18 at 20:41
  • It's perfect to add chomp! Thank you! – yueli Aug 17 '18 at 20:47
  • @yueli Without the (optional) last argument `split` drops all empty trailing fields; when that argument is negative then all fields are returned, empty or not. See documentation: [split](https://perldoc.perl.org/functions/split.html) – zdim Aug 17 '18 at 23:16
2

Very easy, just store the content of the file in the variable $x then find the match and replace:

use strict;
use warnings;
my $filename = "c:\path\to\file.txt";
my $x;
    open(my $fh, '<', $filename) or die "cannot open file $filename: $!";
    {
        local $/;
        $x= <$fh>;
    }
    close($fh);


$x=~s/(\n )/\n0/g;      #starting zeros
$x=~s/( \n)/ 0\n/g;     #ending zeros
$x=~s/( $)/ 0\n/g;      #last zero if no end line on end of string
$x=~s/(^ )/0/g;         #first zero at beginning of string
$x=~s/(    )/   0/g;    #zeros within the matrix

print $x;
Gerhard
  • 22,678
  • 7
  • 27
  • 43
Alan Deep
  • 2,037
  • 1
  • 14
  • 22
  • @yueli I never used perl, but i read the docs to answer your question. ``$filename`` should be replaced by `'temp01'`. If temp01 is located in `C:/` then replace $filename with `'C:/temp01'` – Alan Deep Aug 17 '18 at 20:04
  • Hello, Alan Deep, Thank you so much for your quick response. I replaced the file temp01. But, it comes out: Global symbol "$temp01" requires explicit package name at alan.pl line 4. Execution of alan.pl aborted due to compilation errors. – yueli Aug 17 '18 at 20:08
  • @yueli glad to help! – Alan Deep Aug 17 '18 at 20:08
  • I was wondering that there may a readin file problem. I try to figure it out. – yueli Aug 17 '18 at 20:12
  • @yueli you may post another question for that for this will be out of question topic. (community guidelines) – Alan Deep Aug 17 '18 at 20:15
  • but check out this link: https://stackoverflow.com/questions/4087743/read-file-into-variable-in-perl – Alan Deep Aug 17 '18 at 20:16
  • Thank you for your link. I replaced the temp01, but the result is the same as the input temp01 file 1 2 2 5 4 4 4 4 4 3 4 4 1 1 5 6 4 – yueli Aug 17 '18 at 20:17
  • I edited the answer to correct filehandle path and error handling on die. – Gerhard Aug 18 '18 at 05:29
  • @GerhardBarnard Thank you! – Alan Deep Aug 20 '18 at 20:42