Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Question about Tie::File 1

Status
Not open for further replies.

max1x

Programmer
Jan 12, 2005
366
US
I have read the documentation and I might be running slow today, but for some reason I can't figure out how to implement it.

I have a flat file where I need to modify records with in the file that are passed by a user. There can be a single or multiple records to modify/delete.

Code:
use CGI qw/:all/;
use CGI::Carp qw(fatalsToBrowser);
use Date::Calc qw( Delta_Days Add_Delta_Days );
print "Content-type:text/html\n\n";

@p = (param());
@recordsToDelete = param($p[0]);

open file,"+> /path/to/file" || die "Cannot open file:($!)\
n";
foreach $recordToDelete (sort @recordsToDelete) {
                ($recordNumberToDel) = split (/\s+/,$recordToDelete);
while (<file>) {
        ($recordNumber,$many,$more) = split(/\|/,$_);
                chomp ($recordNumber,$recordNumberToDel);
                s/$recordNumber/Delete/g if ($recordNumber == $recordNumberToDel);
        }
}
close file;

In case of above the file is overwritten with no data.

Alternatively.

Code:
use Tie::File;

tie @array,Tie::File,/path/to/file or die ($!\n);
foreach $recordToDelete (sort @recordsToDelete) {
                ($recordNumberToDel) = split (/\s+/,$recordToDelete);

moving forward, do I need to split the @array and then compare each to record and then modify/delete? I've tried several things, but it seems to give the same end result of a file being overwritten or empty. With @array, I'm also worried about memory consumption.

Any advice...as it seems my brain has already taken to the festivities and refuses to think straight.
 
You didn't really finish the second part of your example. With Tie::File you will just be manipulate the array. I don't see you doing anything with the @array.

I don't have perl on the machine I'm currently on (in training :) )

but something like

tie @array,Tie::File,/path/to/file or die ($!\n);
for my $stuff (@stuffiwannadelete){
@array = grep !/$stuff/, @array;
}

lots of better ways to do it I'm sure..


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Travis,

Enjoying your training there I see :)...

I'm not sure what to do with @array, as from what I'm reading in the docs, I'll have to split the @array, the cmp to the records that are passed and then del?

Like I said, I'm having a constant brain freeze, which even caffine is not helping with...

Reading the docs again...:)
 
Can you give me an example of what will be in your file and what is being passed in from the user?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
The file contains data like so:

1|more|data|here
2|more|data|here
3|more|data|here

The user preforms a data based query and the records are renderd with checkboxes, which they can check to del a single or multiple record. I have given the checkbox the same value as the record number (1 2 3).

The resulting page receives these values, opens the file and can either replace the recordNumber with DEL (so I can skip that record) or completely del the entire line <-- This is where I'm having an issue.
 
can't you just splice the offending elements of the array [-1] of course

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
Not tested in any way what so ever..

Code:
tie @array, 'Tie::File', filename or die ...;

#This is just a guess
@records = param(ToDelete);

#Iterate through each rcords
for my $records (@records) {

	#Iterate through each value of the array by index
	for my $num (0..$#array) {

		#Split the values up on pipe into tmp
		my @tmp = split (/\|/, $array[$num]);

		#Compare $tmp[0] to $records
		if ($records eq $tmp[0]) {
			splice(@array,$num,1);
		}
	}
}
	

untie @array;


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Travis,

Exactly what I was lookin for, with one mod.

Code:
if ($records == $tmp[0])

Paul,

splice did the trick...
 
Yep.. sorry.. I forgot it was numbers.. and again sorry I couldn't test it better but no perl here.. :(

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
You don't need to compare anything if the checkboxes have numbers that correspond to the lines in the file:

1|more|data|here
2|more|data|here
3|more|data|here

You just use the number as the array index minus one.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
I guess we don't know his complete structure..

if it is
1|
2|
3|
4|
5|

and he delete's 3| what if another 3| never gets put in (and I'm assuming he isn't really keeping them in order)?



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
true, which is why I said:

You don't need to compare anything if the checkboxes have numbers that correspond to the lines in the file:

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
picky picky.. you need to bold that if the first time so I see it :D

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Travis,Kevin,

The record numbers do not correspond the line numbers.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top