in reply to Re: Easiest way to filter a file based on user input
in thread Easiest way to filter a file based on user input

So for example, if the user enters -3, all the lines in the file that begin with a numerical value that is greater than 3 will be excluded.

Or if the user enters the value 1, all lines beginning with a value greater than 1 will be excluded.

  • Comment on Re^2: Easiest way to filter a file based on user input

Replies are listed 'Best First'.
Re^3: Easiest way to filter a file based on user input (updated)
by haukex (Archbishop) on Jul 07, 2017 at 11:38 UTC
    So for example, if the user enters -3, all the lines in the file that begin with a numerical value that is greater than 3 will be excluded. Or if the user enters the value 1, all lines beginning with a value greater than 1 will be excluded.

    So based on that description, the user entering -3 is the same as entering 3?

    #!/usr/bin/env perl use strict; use warnings; print "Enter limit: "; chomp( my $limit = <STDIN> ); $limit = abs($limit); open my $in, '<', "file.hairpin" or die $!; open my $sifted, '>', "new_file.hairpin" or die $!; while (<$in>){ next if /^None/; next if /^(\d+)/ && $1 > $limit; print $sifted $_; } close $in; close $sifted;

    Or as a oneliner (where "123" is the limit):

    perl -ne 'print unless /^None/ || ( /^(\d+)/ && $1>123 )' file.hairpin + >new_file.hairpin

    As for your code here, it looks like you don't need to collect your lines in arrays but can write them to the output file directly (or, at the very least you don't need to open your output file once per line of output).

    Update: I just noticed that the sample input in the OP includes decimals and negative numbers, so you'd have to adjust the regex in my example code above accordingly. But before you try to develop really complex regexes, have a look at Regexp::Common::number.

      I tried to implement the special number regex as such:

      #!/usr/bin/env perl use strict; use warnings; use Regexp::Common; print "Enter limit: "; chomp( my $limit = <STDIN> ); $limit = abs($limit); open my $IN, '<', "xt_spacer_results.hairpin" or die $!; open my $SIFTED, '>', "new_xt_spacer_results.hairpin" or die $!; while (<$IN>){ next if /^None/; next if /^( $RE{num}{real}{-places=>2})/ && $1 > $limit; print $SIFTED $_; } close $IN; close $SIFTED;

      But it aborts the program due to  use Regexp::Common; and it states:

      Can't locate Regexp/Common.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at energy_sifter2.pl line 4. BEGIN failed--compilation aborted at energy_sifter2.pl line 4.

      I'm not quite sure how to use modules. Do I download the module somehow and save it in the same file I'm working in?

        I'm not quite sure how to use modules. Do I download the module somehow and save it in the same file I'm working in?

        Brew yourself a big pot of coffee and have a thorough read of A Guide to Installing Modules. You won't look back.

      Thanks for those pointers.