seek_m has asked for the wisdom of the Perl Monks concerning the following question:

hi monks,

i want to parse a text file in the following manner.

input:

sample.txt

12345.pace .......... ..text1.. ...... 12345.slow 123456.pace .......... ..text2.. ...... 123456.slow hyds.pace .......... ..bla bla bla.. uiw.slow

Expected output:

i want to copy the text between each .pace and .slow pattern if and only if the pattern preceeding ".pace" & ".slow" are numbers and put it in to a new file which will have the name preceeding the corresponding .pace as the file name.

for example if i parse the above input file i need to get an output of 2 files with filenames 12345 & 123456 respectively. with the word "text1" inside file 12345 and "text2" inside file 123456 .

kindly help me out?
  • Comment on copying lines in a text file to a new file with a dynamically generated text name
  • Download Code

Replies are listed 'Best First'.
Re: copying lines in a text file to a new file with a dynamically generated text name
by Ratazong (Monsignor) on Feb 14, 2011 at 06:53 UTC

    A typical approach is to have a flag which indicates if you currently need you write to an output-file or not.

    Just read the input-file line-by-line and determine one of the following four situations:

    • You find the start-pattern: now open a new output file based on the number inside the pattern (hint: use a regex). And set your flag
    • You find the end-pattern: just close your output-file and reset the flag
    • You find any other line and the flag is set: write that line to your output-file
    • You find any other line and the flag is not set: ignore that line
    Of course you might want to add some error-checking, too!

    Have fun implementing! If you encounter any Perl-questions, feel free to show your code and where you have issues, so we monks can give you further advice

    HTH, Rata
      Thanks for the idea. i got my thing done..
Re: copying lines in a text file to a new file with a dynamically generated text name
by davido (Cardinal) on Feb 14, 2011 at 08:50 UTC

    Playing with the input record separator so that you're reading in records where the separator is .slow can simplify things a little. This way you're reading 'records' rather than lines, so you don't have to worry about keeping track of state flags.

    use strict; use warnings; my $in_file_name = 'sample.txt'; { local $/ = '.slow'; open my $input, '<', $in_file_name or die $!; while( my $rec = <$input> ) { chomp $rec; next unless $rec =~ m/(\d+)\.pace(.+)$/s; my( $out_file_name, $capture ) = ( $1, $2 ); open my $output, '>', $out_file_name or die $!; print $output $capture; close $output or die $!; } close $input; }

    Untested. But I think it gets the idea across.


    Dave

      Thanks for the effort...i got my work done.
Re: copying lines in a text file to a new file with a dynamically generated text name
by 7stud (Deacon) on Feb 15, 2011 at 00:23 UTC

    If your files aren't too big, you can slurp the file into a single string. Then you can get the info you need with a simple regex that employs a 'g' flag to get all the matches:

    my $text; { local $/ = undef; $text = <DATA>; #"slurp" the whole file } while ($text =~ / (\d+) \. pace (.*?) \d+ \. slow /xmsg ) { print "filename=$1 and text=$2"; } __DATA__ 12345.pace text1 12345.slow 123456.pace text2 123456.slow hyds.pace bla bla bla uiw.slow --output:-- filename=12345 and text= text1 filename=123456 and text= text2

    I'll leave the file creation and the writing of the file for you.

      Thanks
      Thanks