Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

updating/modifying line in a file

by bran4ever (Novice)
on Jun 04, 2006 at 07:20 UTC ( [id://553469]=perlquestion: print w/replies, xml ) Need Help??

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

Hi...how do i modify a line in a file. For example, i have created a webproxy that controls the users/password/download. I have used a function that counts the bytes every time. But i cannot figure out how to update every bytes in the userlist database. like for an example, Tom downloaded 1 megabytes..so its listed in the datbase TOM:<password>:1024 so the next min or so he downloaded 5 megabytes..so i need to update that in the file so 1024 + 5000 = 6024...altogether.. what is the solution? thanks Oh just another mention, i wouldnt' want it to affect other users in the database. so just affect one line as long the person is logged in

Replies are listed 'Best First'.
Re: updating/modifying line in a file
by hesco (Deacon) on Jun 04, 2006 at 07:48 UTC
    If your data store is SQL92 compliant, or even if DBI is willing to think it is, this is easily accomplished with a query of the form below. I've never used them, but as I understand it, DBI has a data base driver that will read a csv file and probbaly has others for other flat file formats, including colon delimited.

    my $sql = "UPDATE tablename SET bandwidth = bandwidth + ? WHERE user = + ?"; my $sth = $dbh->prepare($sql); my $sth->execute($newtraffic,$user);
    However, if you are reading and writing a plain text file, and don't want to wire it up through DBI, you could also grep on $user to find your line, then use something like:

    my @user_fields = split /:/,$_; $user_fields[2] = $user_fields[2] + $newtraffic; my $newline = $user_fields[0].':'.$user_fields[1].':'.$user_fields[2];
    then you can open two file handles, one for reading and one for writing, read the data from the original file, writing it to the new file, using the code above wrapped in a conditional checking for your $user (if(m/$user/){}), to massage it as it goes by.

    -- Hugh

    if( $lal && $lol ) { $life++; }
      open two file handles at the same time?
Re: updating/modifying line in a file
by hesco (Deacon) on Jun 04, 2006 at 08:21 UTC
    Yes, two handles at once, like so:

    open(DB_RESULT,">/path/to/result/db/file"); open(DB_SRC,"/path/to/source/db/file"); while (<DB_SRC>){ if($_ ~= /$user/){ my @user_fields = split /:/,$_; $user_fields[2] = $user_fields[2] + $newtraffic; my $newline = $user_fields[0].':'.$user_fields[1].':'.$user_fields +[2]; print DB_RESULT, $newline; } else { print DB_RESULT, $_; } } close(DB_SRC); close(DB_RESULT); my $result = `mv /path/to/result/db/file /path/to/source/db/file`;
    There may be some slick way to do this with only one file open overwriting only the line you are concerned with, but it is not apparent to me at this late hour. And generally I am of the mind that it is more important to ensure that a program works than that it is fast or fancy.

    if( $lal && $lol ) { $life++; }
      Hello again, i am at university right now, and for the TIE::FILE does nto work at all.... i tried..but i m not sure if its right i will paste this code
      open(data,"userlist.txt") or di +e "$@"; while ($line = <data>) { @details = split(/:/,$l +ine); if ($name[0] eq $detail +s[0]) { print "check -----> $de +tails[0] , $details[1] ,$downloadTotal \n"; open(FH, ">download +temp.txt") or die "$@"; print "check 2 ---- +-> $details"; print(FH $downloadT +otal); open(FH,">>userlis +t.txt") or die "$@"; $details[2] = $ det +ails[2] + $downloadTotal; $newline = $details +[0].':'.$details[1].':'.$details[2]; print(FH $newline); + }
      i checked the userlist.txt its like this after this: kevin:12345678: dex:12345678:11955436 brandon:12345678:kevin:12345678:12348kevin:12345678:134kevin:12345678:135
Re: updating/modifying line in a file
by mickeyn (Priest) on Jun 04, 2006 at 08:15 UTC
Re: updating/modifying line in a file
by CountZero (Bishop) on Jun 04, 2006 at 19:05 UTC
    You should use a real database to store the userdata, as you will very likely get bitten by race conditions and locking a single line of the userlist file will not work.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

      CountZero is definitely right that using a database will be easier and more efficient than dealing with text files and locking. And remember that DB_File and DBD::SQLite count as databases, even though they don't require any kind of server.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-04-25 08:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found