tags:

views:

254

answers:

2

I'm trying to read in a file with names and addreses. It may look like this:

John Doe
123 Main Street
My Town, US 12345

Ralph Kramden
c/o Joe
999 North Lane
YourTown, US 22839

Where there is always a line between records. But I don't know how to tell Perl that the next X lines are all one record. (And X can vary).

How can that be done?

+8  A: 

From perldoc perlvar:

$/
The input record separator, newline by default. This influences Perl’s idea of what a "line" is. Works like awk’s RS variable, including treating empty lines as a terminator if set to the null string. (An empty line cannot contain any spaces or tabs.) You may set it to a multi‐character string to match a multi‐character terminator, or to "undef" to read through the end of file. Setting it to "\n\n" means something slightly different than setting to "", if the file contains consecutive empty lines. Setting to "" will treat two or more consecutive empty lines as a single empty line. Setting to "\n\n" will blindly assume that the next input character belongs to the next paragraph, even if it’s a newline. (Mnemonic: / delimits line boundaries when quoting poetry.)

So try this:

{
  open my $fh, "<", $input_file;
  local $/ = "";
  while(<$fh>) {
    # each loop, $_ will be a different record
    # the first will be "John Doe\n123 Main Street\nMy Town, US 12345\n\n"
    # etc.
  }
}
Chris Lutz
That's awesome. Thanks, Chris.
Pistol
One nice thing is that, as said in the `perldoc` quote, you can set it to `"\n\n"` to skip one blank line, or `"\n\n\n"` to skip two blank lines, or `""` to skip any number of blank lines, which lets you build a more lenient "parser", which usually makes other people's lives easier.
Chris Lutz
+1  A: 
$/ = "";

to treat empty line as "record separator".

Alex Martelli
dup http://stackoverflow.com/questions/1365683/_/1365696#1365696
Brad Gilbert