in reply to Write in files

Thank you guys for your help. I will have a look on Text:CSV as soon as possible. The RegEx aren't the Problem. I know how to match the Strings. The Problem is that i don't know how to overwrite the line with my new line, I'll give you an example: my first thoughts were something like this:
open FILEHANDLE, "/root/Desktop/file1.txt"; open FILEHANDLE2,">>", "/root/Desktop/file2.txt"; while (my $line = <FILEHANDLE>) { $line =~ /RegEx/i; my $telefonnummer = $1; my $name = $2; foreach (my $line2 = <FILEHANDLE2>) { $line2 =~ /RegExp/i; my $name2 = "$1,$2"; if ($name =~ /$name2/i) { $line2 = "$line2;+49$telefonnummer"; } } }
I hope that it doesn't look to strange :) The Problem in this code is that i can't simply print the  $line2 = "$line2;+49$telefonnummer"; line in the file. If that Code wont work at all please tell me, if it would work with some modifications please tell me too. :D Thanks.

Replies are listed 'Best First'.
Re^2: Write in files
by hdb (Monsignor) on Nov 18, 2013 at 09:47 UTC

    The usual way to do this, is to first read the first file into a hash, basically creating a phone directory:

    open my $fh, "<", "/root/Desktop/file1.txt"; my %verzeichnis; while (my $line = <$fh>) { $line =~ /RegEx/i; my $telefonnummer = $1; my $name = $2; $verzeichnis{lc $name} = $telefonnummer; } close $fh;

    In a second loop (rather than a nested loop) afterwards, you would extract the name from each line, do a lookup in the hash and then write the result to a new file. At the end you can then replace your second file with the new file.

    open my $fh2, "<", "/root/Desktop/file2.txt"; open my $new, ">", "/root/Desktop/file2.new"; while (my $line2 = <$fh2>) { chomp $line2; $line2 =~ /RegEx/i; my $name2 = "$1,$2"; print $new $line2; if( defined $verzeichnis{lc $name2} ) { print $new ";+49".$verzeichnis{lc $name2}; } print $new "\n"; } close $fh2; close $new;

    Updated a few of typos.

      I have a few questions to your code. what exactly does the code  $verzeichnis{lc $name} = $telefonnummer; and
      if( defined $verzeichnis{lc $name2} ) { print $new ";+49".$verzeichnis{lc $name2}; }
      does?

      I haven't worked with  defined and  lc yet...

      Thanks for your efforts!

        defined checks whether or not a key is defined in a hash, in this context it will return true if the name was found in your file 1. lc turns a string into lower case, adding a bit of robustness to the code (I assumed you wanted to do case insensitive matching).

        Generally, there is excellent documentation at http://perldoc.perl.org should you be unfamiliar with a specific function.

        UPDATE: It seems I was a bit tired when writing in this thread. While defined does the job, one really should be using exists. Apologies! A simple introduction into hashes can be found here http://www.tutorialspoint.com/perl/perl_hashes.htm but googling "perl hash" will lead to many more good hits.

Re^2: Write in files
by Random_Walk (Prior) on Nov 18, 2013 at 11:26 UTC

    One problem you will have, if you try to update files 2, is that you can not write a new, longer line, into the middle of file 2, without overwriting the following data:

    # Original file 2: Bloggs,Fred\n Conner,Sarah\n Bloggs,Joe\n # file 2 after adding Fred's phone Number Bloggs,Fred,0234687821\n h\n Bloggs,Joe\n
    As you can see, poor old Sarah Conner, has been terminated. Follow the advice to build a new file, and if required remove (or rename) the old file 2, and rename the new one, to the original name, when done.

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!
      how would the code be for editing the original file?

      just because i want to know how that would work :)

        It would be ugly. You would have to copy the file from the end of your current line, update the current line, then put the copied data back, after your new file position. I actually started to write some example code, but it is such a terrible idea I quickly gave up.

        You would probably load the entire file into an array, line per record, then go through the array, keeping a note of how many bytes into the file you are. When you update a record, seek to the end of the old record, before its \n, write the additional info plus new \n, then overwrite the rest of the file with the rest of the records in your array. If you really want to keep the same file, it would be better to build the entire new record set in memory, then blat it all out in one go, overwriting the old file. Power loss, or a crash, will probably cause data loss.

        If you really want to go mad, you could process one record at a time, then when you came to write out, read a few records from your file, write your data, then do a sort of read/write shuffle through the file to move everything up a few bytes. For this approach to work, you would have to be smoking something pretty special ;-)

        Cheers,
        R.

        Pereant, qui ante nos nostra dixerunt!