Perl next if @array (exclude a list of values)

I'm trying to exlude a list of values with perl to process while reading in a file. Is there a way to use the

next if

with a list?

Example:

@array = qw(val1 val2 val3 val6);

while (<>) {
 next if $_ =~ @array;	# values I don't want to process here
 print;			# process the rest here
}

Thanks in advance!

Any time you want to quickly check if something is in a list, use a hash...

%hash=(val1 => 1, val2 => 1,  val3 => 1,  val6 => 1, ); # hash with unwanted items as keys and values that evaluate as true
while (<>) {
 next if $hash{$_};	# values you don't want to process are skipped here
 print;			# process the rest here
}
2 Likes

Using grep

@arry = qw (val1 val2 val3 val3);
while (<>){
  $line=$_;
  next if (grep(/$line/,@arry));
  print ;
}

Hi Pravin,

That will work however, while it will use less memory than a hash, it will use a lot more cycles. you are grepping through the (potentially large array) for every line of the file.

Where you have a static list you wish check against a hash is the preferred solution as you take advantage of the hashing to very quickly return the value.

2 Likes

Will this work with a range?

%hash=(val1 => 1, val2 => 1,  val3 => 1,  val6 => 1, ); # hash with unwanted items as keys and values that evaluate as true
while (<>) {
 print if (/$hash{$_}/ .. /END/);	
}

I am afraid it will not work, regardless of what you are trying to do.
$_ in the while loop will have a new line with it and it will never match any of the %hash keys.
$hash{$_} will evaluate to a 1 if exist and to undef if it doesn't, thus /1/ .. /END/ or /undef/ .. /END/ , which makes a moot condition.

What is it that you are trying to do? The latest seems off from your original query.
Could you post input and desired output examples?

Yes and Thanks.
I'm trying to remove sections of a file based on an input of values.

Here is a sample of the file I'm trying to "edit"

section /total/SMS-MT-FSM-DEL-REP045
country: IN
1280363645.979354_PFS_1_1887728354
begin:03
final:56
END

section /total/SMS-MO-FSM001
country: IR
1280105721.484103_PFM_1_1187616097
final:23
END

section /total/SMS-MT-FSM-DEL-REP095
country: IN
1280363645.729309_PFS_1_1084296392
final:43
END

section /total/SMS-MO-FSM001
country: IR
1280105721.484103_PFM_1_1187616097
final:23
END

section /total/SMS-MO-FSM095
country: MO
1280105721.461090_PFM_1_882824215
begin:12
final:89
END



With a list given to me as:

REP045
REP095

I want to remove the sections of the file related to a list given above.

Desired output:

section /total/SMS-MO-FSM001
country: IR
1280105721.484103_PFM_1_1187616097
final:23
END

section /total/SMS-MO-FSM095
country: MO
1280105721.461090_PFM_1_882824215
begin:12
final:89
END

Given your explanation this should be able to do it. However, your desired output does not match what you explained.

#!/usr/bin/perl
#
use strict;
use warnings;

my @list = qw(REP045 REP095);
my %unwanted = map{$_ => 1} @list;

{
    local $/="\n\n";
    while(<>) {
        my ($id) = (split '-', (split '\n')[0])[-1];
        print if /$id/ and not $unwanted{$id};
    }
}
section /total/SMS-MO-FSM001
country: IR
1280105721.484103_PFM_1_1187616097
final:23
END

section /total/SMS-MO-FSM001
country: IR
1280105721.484103_PFM_1_1187616097
final:23
END

section /total/SMS-MO-FSM095
country: MO
1280105721.461090_PFM_1_882824215
begin:12
final:89
END
1 Like

Thanks much, Aia! I appreciate you looking at this for me!