LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-03-2011, 05:08 AM   #1
casualzone
Member
 
Registered: Jan 2010
Posts: 189

Rep: Reputation: 15
could perl script modify a file directly ??


i still a newbie of perl script, but want to perl script to make my work easier.

command:
hack.pl input.txt target.txt
,where input.txt is user input file, eg the net to be replaced etc
target.txt is the file i want to modify

method #1,
-read in input.txt & process
-read in target.txt & save all the lines into memory
-read line by line & make changes in the memory if matched.
-after that, print to another file target.txt.hack

method #2
-read in input.txt & process
-copy target.txt tp target.txt.hack
-read the target.txt.hack line by line
-no need to save all the line into memory
-modify if matched
(same principle as like user modify in vi)

which one is better? Is the method #2 doable?

could perl script modidy the file directly? i saw one similar example, it uses method #1
 
Old 08-03-2011, 05:15 AM   #2
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by casualzone View Post
...
could perl script modidy the file directly? i saw one similar example, it uses method #1
I am not sure I fully understand your question, but modifying a file in place is almost always a truly bad idea regardless of language.

Reading full file into memory or not is an orthogonal issue. You can easily read small files into memory. You can also map files onto Perl arrays: http://search.cpan.org/search?query=map+file&mode=all -> http://search.cpan.org/~leont/File-M...ib/File/Map.pm , etc.
 
1 members found this post helpful.
Old 08-03-2011, 05:57 AM   #3
Proud
Senior Member
 
Registered: Dec 2002
Location: England
Distribution: Used to use Mandrake/Mandriva
Posts: 2,794

Rep: Reputation: 116Reputation: 116
I believe in method 1 you're talking of producing a copy of the contents of the target.txt file into memory, and then your substitutions as dictated by your input.txt are performed to this copy, and then the result is written to target.txt.hack.
I fail to see how this is modifying the file directly, and how this matches with your similar example statement where this method was used.

Method 2 seems to require a mapping mechanism as Sergei provides, and then I'd question why you'd only map one line at a time, as most systems using Perl would surely be capable of mapping more/all of the file, even if your substitutions are performed per line.

I'm going to question the need to edit the file directly. IIRC under Linux, any process that reads a file will recieve a copy of the contents, and your changes will not be automatically picked up unless the other program is monitoring for alteration timestamp changes or actual file contents changes. You seem to describe producing a second file, and no mention of replacing the first with the second.

I'll also mention you might want to consider how any subsequent program will know when you're done modifying the .hack file, especially with the 2nd/mapped method. With the 1st method, you'd need only consider if the file exists in the filesystem before all its contents is readable by someone immediately opening it, whether if it starts empty and grows or won't be listed until all output is written.
AFAIK the usual method is write out to a tmp file, then lastly rename to the filename you wish others to use.

Last edited by Proud; 08-03-2011 at 05:58 AM. Reason: and->any
 
1 members found this post helpful.
Old 08-03-2011, 06:03 AM   #4
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Proud View Post
...AFAIK the usual method is write out to a tmp file, then lastly rename to the filename you wish others to use.
Yep, that's the usual method.
 
Old 08-03-2011, 01:04 PM   #5
karthik3152
LQ Newbie
 
Registered: May 2011
Posts: 10
Blog Entries: 3

Rep: Reputation: Disabled
I accept with method Two will be the most efficient way.But in Perl method one is possible but it may fail in some cases.

open(FILE,"+<hello.dat");
# "+<" option has to be used for read and writing to the file
@lines=<FILE>;
foreach(@lines)
{
chop;
print; # it is same as print $_;
print "\n";
}
print FILE "\n"."karthik";
close(FILE)

This program can help you to understand better.
The file examples in the site:[url]http://linux-forum-karthik.blogspot.com
can give you a better understanding.
 
0 members found this post helpful.
Old 08-04-2011, 12:06 AM   #6
casualzone
Member
 
Registered: Jan 2010
Posts: 189

Original Poster
Rep: Reputation: 15
sounds like the 2nd method is a bad idea (modifying a file directly)
 
Old 08-04-2011, 12:51 AM   #7
casualzone
Member
 
Registered: Jan 2010
Posts: 189

Original Poster
Rep: Reputation: 15
this is about method #1 (simplified one)
is it the common way of writing perl?

Code:
system(clear);
open($INPUT, $ARGV[0]) || die('No input_net file');
        @INPUT_FILE=<$INPUT>;        #save the entire file into memory
        $INPUT_LINE=@INPUT_FILE;     #total line
close($INPUT);
$line=0;
while($line < $INPUT_LINE){

        do_something...and change the content in @INPUT_FILE
$line++;
}

my $outfile = "$ARGV[0]".".hack" ;
open( OUTFILE, "> $outfile" ) ||  die("Can't open file for write.\n");

#print out all after the all changes
foreach(@INFILE)
{
        print(OUTFILE "$_\n");
}

close(OUTFILE);
 
Old 08-04-2011, 02:35 AM   #8
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by casualzone View Post
this is about method #1 (simplified one)
is it the common way of writing perl?

Code:
system(clear);
open($INPUT, $ARGV[0]) || die('No input_net file');
        @INPUT_FILE=<$INPUT>;        #save the entire file into memory
        $INPUT_LINE=@INPUT_FILE;     #total line
close($INPUT);
$line=0;
while($line < $INPUT_LINE){

        do_something...and change the content in @INPUT_FILE
$line++;
}

my $outfile = "$ARGV[0]".".hack" ;
open( OUTFILE, "> $outfile" ) ||  die("Can't open file for write.\n");

#print out all after the all changes
foreach(@INFILE)
{
        print(OUTFILE "$_\n");
}

close(OUTFILE);
No, it is common method for writing "C". Get back to the tutorials -> http://perldoc.perl.org/perlintro.html -> http://perldoc.perl.org/perlsyn.html , look up 'foreach'.
 
Old 08-04-2011, 02:56 AM   #9
casualzone
Member
 
Registered: Jan 2010
Posts: 189

Original Poster
Rep: Reputation: 15
while($line < $INPUT_LINE){

do_something...and change the content in @INPUT_FILE
$line++;
}

Change the above to:

foreach( @INPUT_FILE)
{
do_something...and change the content in @INPUT_FILE
}
 
Old 08-04-2011, 04:12 AM   #10
casualzone
Member
 
Registered: Jan 2010
Posts: 189

Original Poster
Rep: Reputation: 15
open($INPUT, $ARGV[0]) || die('No input_net file');
@INPUT_FILE=<$INPUT>; #save the entire file into memory
$INPUT_LINE=@INPUT_FILE; #total line
close($INPUT);

this step will be put a large file into memory.
is there any other way?
 
Old 08-04-2011, 10:58 AM   #11
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by casualzone View Post
open($INPUT, $ARGV[0]) || die('No input_net file');
@INPUT_FILE=<$INPUT>; #save the entire file into memory
$INPUT_LINE=@INPUT_FILE; #total line
close($INPUT);

this step will be put a large file into memory.
is there any other way?
Why do you need your whole input file in memory ?
 
Old 08-04-2011, 11:50 PM   #12
casualzone
Member
 
Registered: Jan 2010
Posts: 189

Original Poster
Rep: Reputation: 15
It is easier to edit. (i know this method, at least the test case work if i load into memory since i edit from memory)
Besides this, I have tried other method which writing to a new file but it does not work


Flow:
-Open input file
-read input file line by line #step2
-open target file
-read target line by line
-if matching --> do replacement
-print the line into a new file
-repeat the step 2

## 2nd iterations
-read input file line by line
-open target file
-read target line by line
-if matching -->do replacement
-print the line in to a new file (the problem is here , it only changes the current edit, the previous changes is not written)
-repeat the step2

(the flow is the simplified one, I use simple replacement as test case.)

I think i got to overwrite target file after printing a new file.

Last edited by casualzone; 08-04-2011 at 11:51 PM.
 
Old 08-06-2011, 04:58 PM   #13
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
this will change THIS to THAT in file

Code:
perl -pie 's/this/that/g' file ...
this will create a backup .bak

Code:
 perl -pi.bak  -e 's/END/end/' file ...
or you can add the switches to a more complex script
Code:
#!/usr/bin/perl -i.bak  -p

s/work/PLAY/g;
s/fish/chips/g;
 
Old 08-07-2011, 12:19 AM   #14
casualzone
Member
 
Registered: Jan 2010
Posts: 189

Original Poster
Rep: Reputation: 15
hi bigearsbilly,
thx for the information.

I still need to improve the flow because my script for my work need some manipulations rather than simple substitution.
For simple substitution, i can manage to achieve by using vi, instead of perl script.
 
Old 08-07-2011, 03:32 AM   #15
fl0
Member
 
Registered: May 2010
Location: Germany
Distribution: Slackware
Posts: 105

Rep: Reputation: 34
Hi,

you can use Tie::File to edit Files in place


rgds flo
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
modify the perl script so that I could apply the script to all the files casualzone Linux - Software 3 05-06-2011 04:23 AM
[SOLVED] [perl] parse and modify file without creating a copy frznchckn Programming 3 11-04-2010 05:38 PM
modify the definitions set on the package's control file directly for your repository Teenna Linux - Newbie 5 12-05-2008 05:32 PM
How to modify a field in few lines in a file and save the new file - in Perl rounak94 Programming 1 10-02-2008 07:43 PM
Modify Perl script to work with txt - Permissions script joangopan Programming 4 09-14-2007 09:20 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:18 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration