Gary Gary - 4 months ago 11
Perl Question

Capture group stored as variable, Substitution operator returns it as blank?

#!/approot/opt/bin/perl
use strict;

my $file = $ARGV[0];
open FILE, $file or die;
my $line;

while (<FILE>) {

if (m/create unique clustered index \S+ on \S+ \(([^\)]+)\)/) {
$line = $1;
}
s/chargeable_items/$line/;

print;
}


Here is the text file I am trying to make this work with but everytime it attempts to replace it. It replaces the string with a blank.

CREATE TABLE t_test
(
system_name varchar(20) NOT NULL,
server_type smallint NOT NULL,
chargeable_system bit NOT NULL,
chargeable_items bit NOT NULL
)
create unique clustered index host_idx on dbo.t_host (system_name, server_type, environment)
create nonclustered index tt_host on dbo.t_host (N.A.)


Everytime it does the substitution operator it replaces "chargeable_items" with a blank value as shown below

CREATE TABLE t_test
(
system_name varchar(20) NOT NULL,
server_type smallint NOT NULL,
chargeable_system bit NOT NULL,
bit NOT NULL
)
create unique clustered index host_idx on dbo.t_host (system_name, server_type, environment)
create nonclustered index tt_host on dbo.t_host (N.A.)

Answer

You are reading file line-by-line in while loop.

At line

chargeable_items   bit NOT NULL

you have not yet set $line to any value, so chargeable_items is replaced with empty value. You only set $line later on line

create unique clustered index host_idx on dbo.t_host (system_name, server_type, environment)

but $line is never used after that since there is no chargeable_items after that line.

Working solution would be to read whole file at once and then do matching and substitution:

#!/approot/opt/bin/perl
use strict;

my $file = $ARGV[0];
open FILE, $file or die;
local $/;
my $data = <FILE>;

if ($data =~ m/create unique clustered index \S+ on \S+ \(([^\)]+)\)/) {
  my $line = $1;
  $data =~ s/chargeable_items/$line/;
}

print $data;

Here local $/ sets special variable $/ (input record separator) to undefined value locally, so that <FILE> will read whole file at once, instead of line-by-line, which is normal behaviour.