Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Writing to a file

by victorz22 (Sexton)
on May 05, 2017 at 20:19 UTC ( [id://1189607]=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks, I am trying to replace text in a file and write it to a copy of that file but i get an error where the only some of the text gets replaced and the rest is just added on to the beginning of the file(I don't want it there). Please let me know if you have any questions, and Thank You!

the data that needs to be replaced is just a bunch of paths to certain + directories and it looks kinda like this #data to replace old/path/to/some/file another/old/path/to/some/file one/more/old/path/to/some/file #desired replacement new/path/to/some/file another/new/path/to/some/file one/more/new/path/to/some/file
#Code to read in file my $inputFile = 'file.txt'; my $fileContent = do { open(my $fileHandle, $inputFile ) or die "Could not open file +'$inputFile' $!"; local $/; <$fileHandle>; }; #replace search paths with data in hash per key, $oldSearchPat +hs and %searchPaths are initialized elsewhere foreach my $key (keys %searchPaths){ $fileContent =~ s/\Q$oldSearchPaths\E/\n$searchPaths{$key}/; } #code to write to file my $filename = 'fileCopy.txt'; open(my $fh, '>', $filename) or die "Could not open file '$filenam +e' $!"; print $fh $fileContent; close $fh; print "Writing to File Done! \n";

Replies are listed 'Best First'.
Re: Writing to a file
by kcott (Archbishop) on May 06, 2017 at 05:33 UTC

    G'day victorz22,

    Here's how I might have tackled this (pm_1189607_read_replace_write.pl).

    #!/usr/bin/env perl -l use strict; use warnings; use autodie; use File::Spec; my ($infile, $outfile) = qw{pm_1189607_input pm_1189607_output}; my %new_path_for = ( 'old/path/to/some/' => 'new/path/to/some/', 'another/old/path/to/some/' => 'another/new/path/to/some/', 'one/more/old/path/to/some/' => 'one/more/new/path/to/some/', ); { open my $in_fh, '<', $infile; open my $out_fh, '>', $outfile; while (<$in_fh>) { chomp; my ($vol, $dirs, $file) = File::Spec::->splitpath($_); $dirs = $new_path_for{$dirs} if exists $new_path_for{$dirs}; print $out_fh File::Spec::->catpath($vol, $dirs, $file); } }

    Sample run:

    $ cat pm_1189607_input old/path/to/some/file another/old/path/to/some/file one/more/old/path/to/some/file path/to/keep/as/is/file $ pm_1189607_read_replace_write.pl $ cat pm_1189607_output new/path/to/some/file another/new/path/to/some/file one/more/new/path/to/some/file path/to/keep/as/is/file $

    [Over the past fortnight or so, you've posted much the same question repeatedly: this has already been noted, more than once, in responses to your earlier posts. You appear to be ignoring not just the advice given, but also requests for additional information that would help us to help you. You're under no obligation to take our advice or answer our questions; however, if you choose that course of action, you're really just wasting your time and ours with these multiple postings.]

    — Ken

Re: Writing to a file
by shmem (Chancellor) on May 06, 2017 at 06:43 UTC

    Looks fine to me (except some indentation). Doesn't work? why? Well, the problem might be in what you omitted to show:

    # replace search paths with data in hash per key, # $oldSearchPaths and %searchPaths are initialized elsewhere

    What is in $oldSearchPaths? Shouldn't this also be a hash, and then

    $fileContent =~ s/\Q$oldSearchPaths{$key}\E/\n$searchPaths{$key}/;

    this would do the job? And why is there a leading \n in the replacement part?
    Also, you might want to juse the s and g modifiers for s/// if there are multiple ocurrences of paths in the file you are processing. See perlre and Regexp Quote Like Operators.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Writing to a file
by GotToBTru (Prior) on May 05, 2017 at 20:57 UTC

    It really helps us help you when you provide a Short, Self-Contained Correct Example.

    But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

Re: Writing to a file
by marinersk (Priest) on May 06, 2017 at 13:41 UTC

    Hello, victorz22. I am writing this in hopes that you actually want to get better at using Perl.

    I've rewritten your script, but I had to guess at some of your intentions.

    I pointedly avoided the use of modules so you could see the logic.

    This is not how I would write the code. This is strictly for your learning benefit.

    #!/usr/bin/perl use strict; use warnings; # Using this array to simulate the input file (reduces code size) my @Inpbuf = ( 'old/path/to/some/file', 'another/old/path/to/some/file', 'one/more/old/path/to/some/file', 'bad/cold/example/old/path/to/some/file', ); # This is the old path my $Oldpat = 'old'; # This is the desired new path my $Newpat = 'new'; # This is a horrible way to specify the directory separator (reduces c +ode size) my $Dirsep = "/"; my $Dirrgx = quotemeta $Dirsep; # Loop through the input and demonstrate two ways to perform the adjus +tment foreach my $inpbuf (@Inpbuf) { # Translation here so we can support future multiple translation l +ogic my $oldrgx = quotemeta $Oldpat; # This should produce unwanted results on fourth line of data my $tstbuf = $inpbuf; $tstbuf =~ s/$oldrgx/$Newpat/g; print " Risky transation: [$inpbuf] -> [$tstbuf]\n"; # This probably has a higher rate of intended results my @inpelt = split /$Dirrgx/, $inpbuf; my @outelt = (); foreach my $inpelt (@inpelt) { my $outelt = $inpelt; $outelt =~ s/^$oldrgx$/$Newpat/; push @outelt, $outelt; } my $outbuf = join $Dirsep, @outelt; print "Proper translation: [$inpbuf] -> [$outbuf]\n"; print "\n"; } exit; __END__

    My results:

    P:\>chg10.pl Risky transation: [old/path/to/some/file] -> [new/path/to/some/file +] Proper translation: [old/path/to/some/file] -> [new/path/to/some/file +] Risky transation: [another/old/path/to/some/file] -> [another/new/p +ath/to/some/file] Proper translation: [another/old/path/to/some/file] -> [another/new/p +ath/to/some/file] Risky transation: [one/more/old/path/to/some/file] -> [one/more/new +/path/to/some/file] Proper translation: [one/more/old/path/to/some/file] -> [one/more/new +/path/to/some/file] Risky transation: [bad/cold/example/old/path/to/some/file] -> [bad/ +cnew/example/new/path/to/some/file] Proper translation: [bad/cold/example/old/path/to/some/file] -> [bad/ +cold/example/new/path/to/some/file] P:\>

Re: Writing to a file
by Anonymous Monk on May 05, 2017 at 20:29 UTC
    $ cat file.txt old/path/to/some/file another/old/path/to/some/file one/more/old/path/to/some/file $ perl -pe 's#\bold(?=/path/to/some/)#new#g' file.txt new/path/to/some/file another/new/path/to/some/file one/more/new/path/to/some/file
    But I don't think that's what you meant. That means your sample input & output isn't representative enough of the actual problem.

      well that sample i gave isn't my actual data but i do need a block of paths to be replaced, also I need a solution that works in a program and not a command line call. Thanks anyways though.

        Just for future reference, a "command line call" can usually be converted into a "program" fairly easily:

        c:\@Work\Perl\monks>perl -MO=Deparse -pe "s#\bold(?=/path/to/some/)#ne +w#g" LINE: while (defined($_ = <ARGV>)) { s[\bold(?=/path/to/some/)][new]g; } continue { die "-p destination: $!\n" unless print $_; } -e syntax OK
        See O and B::Deparse.


        Give a man a fish:  <%-{-{-{-<

        Translating such a Perl one-liner into an actual program is fairly simple, and we can help you. But the real point is this: is this what you need?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1189607]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (2)
As of 2024-04-26 07:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found