Howto works with record separator in Perl

I have data that looks like

-- read50_1: read1391364_2,read3529226_1, -- read46_2: read916_1,read178252_2,read1336397_1,read1824459_2, read916_1: read0_1 -- read34_1: read209771_2, -- read32_2: read520377_2, 

I want to make write access, excluding the separator "-".

But why doesn't this code do this?

 my $INFILE_file_name = "myfile.txt"; # input file name my $content = ''; open ( INFILE, '<', $INFILE_file_name ) or croak "$0 : failed to open input file $INFILE_file_name : $!\n"; { local $/ = "--"; $content = <INFILE>; print "$content\n"; } close ( INFILE ); # close input file 
+4
source share
7 answers

First of all, I assume that you meant

 local $/ = "--\n"; # or maybe "\n--\n" 

(If you use "\n--\n" , the first line will no longer be considered the record separator, but will be part of the first record. Perhaps you need to read this first line -- before changing $/ .)

Remember that $/ not deleted by the <IN> operator. Use chomp to do this.

Secondly, the file begins with a record separator, so the first record will be empty.

 { local $/ = "--\n"; while ($content = <INFILE>) { chomp $content; print "$content\n" if $content; # Skip empty records } } 
+3
source
 #!/usr/bin/env perl use Modern::Perl; use autodie; use Data::Dump 'pp'; open my $file, "<", "input.txt"; { local $/ = "--\n"; say pp <$file>; } close $file; 

And the conclusion:

 ( "--\n", "read50_1: read1391364_2,read3529226_1,\n--\n", "read46_2: read916_1,read178252_2,read1336397_1,read1824459_2,\nread916_1: read0_1\n--\n", "read34_1: read209771_2,\n--\n", "read32_2: read520377_2,\n", ) 

In other words, reading does not separate the input delimiter. You might want something like this:

 open my $file, "<", "input.txt"; { local $/ = "--\n"; for (<$file>) { chomp; s/\n//g; say "<$_>"; } } close $file; 

What gives:

 <> <read50_1: read1391364_2,read3529226_1,> <read46_2: read916_1,read178252_2,read1336397_1,read1824459_2,read916_1: read0_1> <read34_1: read209771_2,> <read32_2: read520377_2,> 

As an additional note, you should use tri-arg open , and you might be interested in autodie , so you don't have to write or die patterns.

+2
source

You can also just do:

 while(<INFILE>) { print unless(/\s*--\s*/); } 
+2
source

When using the record separator, there is a possibility, this is not a good solution, if only '- implies some significant grouping of data (which will be used). If the goal is to simply filter out the '-', use loop control.

 use strict; use warnings; my $file = 'myFile.txt'; open my $fh, '<', $file or die "Unable to open $file: $!"; while ( <$fh> ) { # Read text file line-by-line next if /^--/; # Skips current line if it begins with '--' print; # Will only execute if line doesn't begin with '--' } close $fh; 
+2
source

Try the following:

 my $INFILE_file_name = "myfile.txt"; my @content = ( ); open ( INFILE, '<', $INFILE_file_name ); @content = <INFILE>; close ( INFILE ); foreach my $line (@content) { $line =~ s/^\s+//; $line =~ s/\s+$//; if ($line eq '--') { next; } print $line . "\n"; } 

From this, you will be able to access records line by line, without a separator. Also, if you just want to put it in a single variable instead of an array, you can simply:

 $file .= $line . "\n"; 
+1
source

$content = <INFILE> selects only the next line that ends with the characters in $/ . It must be wrapped in a loop to get all the rows.

 while ( $content = <INFILE> ) { chomp $content; print "$content\n"; } 

Modern Perl users stay away from descriptor descriptors. Instead, use lexical variables as file descriptors. To find out why lexical variables are preferable to descriptor descriptors, read: Upper case handwritten files .

+1
source

local $ / = "- \ n"; while (nibble ($ _ =)) {print;}

+1
source

All Articles