Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Replace specific lines specific range of characters.

by govindkailas (Acolyte)
on Apr 04, 2013 at 11:50 UTC ( #1026979=perlquestion: print w/replies, xml ) Need Help??
govindkailas has asked for the wisdom of the Perl Monks concerning the following question:


I have file which is of ~1gb, my requirement is to replace the specific lines specified range of characters with the provided string. I am using perl 5.8, below is my code. Due to the interpolation oneliners are not getting the variables vaule.

die "usage: perl $0 file_nm line_nb col_start col_end replacement \n" +unless @ARGV; die "Invalid number of arguments \nusage: perl $0 file_nm line_nb col_ +start col_end replacement \n" if @ARGV ne 5; my ($file_nm,$line_nb,$col_start,$col_end,$string)=@ARGV; chomp($content=`perl -ne "print if $. == ${line_nb}" $file_nm`); #get +the specific line from file chomp ($replacement=`perl -ne "substr($content, $col_start, $col_end, +$string);print $content"`); #get the replaced line #print "New content \n$content \n"; `perl -pi -e "s/$content/$replacement/" $file_nm`; #now substitute the + whole line with the new replaced line

Arguments to the script are File name line number ,in which the replacement should take place replacement start position replacement end position string to replace with Suggestions are welcome

--- Update --- Wrote a perl script finally
use File::Basename; die "usage: perl $0 file_nm line_nb pos_start-pos_end replacement \n" +unless @ARGV; die "Invalid number of arguments \nusage: perl $0 file_nm line_nb pos_ +start pos_end replacement \n" if @ARGV ne 5; my ($file_nm,$line_nb,$pos,$string)=@ARGV; my ($pos_start,$pos_end)=split (/-/,$pos); $file_nm=File::Basename::basename($file_nm); open(READ_HN,"$file_nm") or die "Cant open $file_nm $! \n"; open(WRITE_HN,">${file_nm}.updated") or die "Cant write to ${file_nm}. +updated $! \n"; #chomp($content=`perl -ne "print if $. == ${line_nb}" $file_nm`); while(<READ_HN>) { if ($. == $line_nb) { substr($_, $pos_start, $pos_end, $string); } print WRITE_HN "$_\n"; } close(WRITE_HN); close(READ_HN);

Replies are listed 'Best First'.
Re: Replace specific lines specific range of characters.
by roboticus (Chancellor) on Apr 04, 2013 at 12:10 UTC


    You've certainly chosen an odd way to code your solution.

    Is there any reason you're invoking perl four times when once would do?

    I suggest you convert your code to a simple loop to locate the line, and then perform the substitution.


    When your only tool is a hammer, all problems look like your thumb.

Re: Replace specific lines specific range of characters.
by hdb (Prior) on Apr 04, 2013 at 13:05 UTC

    From what I understand you want to replace a bit of text in a given row and columns with some other text. This would be like this:

    use strict; use warnings; my ($file_nm,$line_nb,$col_start,$col_end,$string)=@ARGV; open FILE, "<", $file_nm or die "Cannot open file $file_nm!\n"; open OUT, ">", "~$file_nm" or die "Cannot open temp file ~$file_nm for + writing!\n"; while(<FILE>){ substr( $_, $col_start, $col_end-$col_start+1 ) = $string if $.==$ +line_nb; print OUT $_; } close OUT; close FILE; rename( "~$file_nm", $file_nm );

    Another comment: Your last line substituting the whole line with the new one would replace all lines of the same content. So if the target line happens to appear multiple times it would be replaced multiple times...

    UPDATE: Writing file in place added.

Re: Replace specific lines specific range of characters.
by TJPride (Pilgrim) on Apr 04, 2013 at 12:12 UTC
    I understand most of that, but it might help to have sample input / output so we can be sure we're programming the right code. And why exactly is your script a series of executed one-liners? Why not just do it like a regular Perl script? First time I've ever seen something done this way.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1026979]
Approved by Corion
Discipulus .. per ear!
[LanX]: LOL
[choroba]: we used to play more :)
Discipulus played the guitar in a ska band 12 elemnts, very fun
[LanX]: well ... the prize for worshipping satan is high ...
[Discipulus]: you value too much your soul LanX
[Eily]: LanX: you mean people end up losing their health insurance?

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (9)
As of 2017-03-24 12:35 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (301 votes). Check out past polls.