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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Search text file and open record

Status
Not open for further replies.

daveryan

Programmer
Sep 1, 2005
9
GB
I'm working on a script that asks for a 4 digit number.
When a number is then typed in, a search is made of an external text file to see if the number already exists.

The text file is in this format:
6393,Smith
2473,Jones
3769,Baker
6369,Evans

If the number exists, then that record only is to be displayed on screen and not written to the external file. If the record does not exist, then it is written to the external file.

My problem is my code displays all records and still writes the record to the external file.

Here is a cut down version of my code:

#!c:\perl\bin\perl.exe

print("Enter your four digit customer reference number.\n");
$ref=<STDIN>;
chomp($ref);

while ($ref!~m/^\d{4}$/)
{
print("Not a valid number, please enter your correct customer reference number.\n");
$ref=<STDIN>;
}

open(RECORDS,"Data.txt") || die "Couldn't open file:$!";
while(<RECORDS>)
{
if ($ref=~m/^\d{4}/) {
print"$_";
}
}
close(RECORDS);

open (RECORDS,">>Data.txt") || die "Couldn't open file:$!";
print RECORDS "$ref\n";
close(RECORDS);


Can anyone please help me?




Dave
 
I believe you need an elsif around the last opening and closing of RECORDS.

so.. if $ref matches the 4 digit number print the record to screen. In all other cases write $ref to the Data.txt.

the last open and close and teh writing to the file is done all the time in your script.

InDenial

 
Code:
#!/usr/bin/perl -w
use strict;

my $recno = shift;
exit unless $recno =~ /^\d{4}$/;
while(<>) {
  if(/^$recno,/) {
    print;
  } else {
    print STDERR $_;
  }
}

Run with "perl script.pl 2473 2>filtered_file.dat"




(slowly healing) Trojan.
 
InDenial......

The reason for the last open and close is for the other data to be entered into the text file, such as name and date of birth, so I'll have to remove the $ref from that one.

I see what you mean about using a elsif, but how do I match the exact 4 digit code from the text file to the one just entered? How I have it at the moment, it just looks to see if there is a 4 digit code of any kind.

TrojanWarBlade......

I don't totally understand your script, or how it would fit in with mine.

Thanks for replying, could you please help me further.


Dave
 
My code writes the selected record to STDOUT (the first print) and the other records to STDERR (the second print).
I thought that you were trying to split your source file to filter just the selected record to a different file (or the screen). My simple little script does just that.
I really don't quite understand what your script is trying to do but it doesn't look right to me.
Why not give my script a quick go and see if it's anywhere near what you wanted.
If you need to embed the filenames then you already have code for that in your own script.
As for user input, if it's too much to ask that the user runs the script with the number as a param then, again, you already have code to do that bit.




(slowly healing) Trojan.
 
This would be perfect for implementing a DB_File to handle this. Perl has a nice built in psuedo database functionality. Works very similar to a hash, but is stored outside of the program so you can use it across users.

Some sample code is below.

Code:
#! /usr/bin/perl

use strict;

my %votes;
my $filename = '/home/user1/picsdb';
my $dir = '/home/user1/pictures';

dbmopen %votes, $filename, 0777 or die "Can't open database: $!";

opendir (PICDIR, "$dir") or die "Cannot open Directory: $!";

while (my $contents = readdir(PICDIR))
{
	my $match;

	if (-d $contents)
	{
		next;
	}

	foreach my $key (sort keys %votes)
	{
		if (($contents eq $key))
		{
			$match = 1;
			print "$key matches an existing record.  Moving to next.<br />\n";
		}
	}
	
	if (!$match)
	{
		$votes{$contents} = '0';
	}
}

foreach my $key (sort keys %votes)
{
	print "$key\t$votes{$key}<br />\n";
}

dbmclose %votes;

close (PICDIR);

- Rieekan
 
this matches all lines that start with four digits which is why it prints all lines:

if ($ref=~m/^\d{4}/) {
print"$_";

you need to match the four digits that were entered by the user which is what TrojanWB was showing you:

Code:
exit unless [b]$recno[/b] =~ /^\d{4}$/;
while(<>) {
  if(/^[b]$recno[/b],/) {
    print;

personally I would use split() to find the match but the regexp will work too.
 
is this what you need?

Code:
[b]#!/usr/bin/perl[/b]

prompt();

while (<STDIN>) {
  chomp;
  if (/^\d{4}$/) {
    $id = $_;
    open (IN, "< data.txt");
    @records = <IN>;
    print grep(/$id/, @records);
    close IN;
  } else {
    open (OUT, ">> data.txt");
    print OUT "$_"; # not quite sure where the name will come from?
    close OUT;
  }
  prompt();
}

sub prompt {
  print "enter number: ";
}


Kind Regards
Duncan
 
Why not try substr?
It'd probably be the fastest solution
Code:
print if substr($_,0,4) eq $recno;
Food for thought! ;-)




(slowly healing) Trojan.
 
Good point! After all, there is a comma after the number so that would work


Kind Regards
Duncan
 
Bit difficult to explain - I am referring to his other post. My comment makes no sense unless you have seen it. Sorry for confusion.


Kind Regards
Duncan
 
You have seen it - "checking for a 4-digit number" - now you have more idea what i am going on about...


Kind Regards
Duncan
 
I'm a bit hungover at the moment so can't get my head around it.

Thanks for all the suggestions, I'll give it another go on Monday when my head is clearer.

I'll let you know how it goes.





Dave
 
I've just about solved the problem.
The only problem is it always writes a second text file, any ideas why?

Here is the code:

Code:
#!c:\perl\bin\perl.exe

$records = "Data.txt";
if(-e $records) {
	open(RECORDS, "<Data.txt") or die "Could not open file.";
}
else {
	open(RECORDS, ">Data.txt") or die "Could not open file.";
	close(RECORDS);
}

print("Enter your four digit customer reference number.\n");
$ref=<STDIN>;
chomp($ref);

while ($ref!~m/^\d{4}$/)
    {
        print("Not a valid number, please enter your correct customer reference number.\n");
        $ref=<STDIN>;
    } 
$numExist = 0;
while(<RECORDS>) {
	# $numExist = 1;
		foreach($_){
		if($_=~m/^$ref/){
			print("$_");
			$numExist++;
			last;
		}
	}
}
if($numExist == 0) {
	open(RECORDS, ">>Data.text") or die "Could not open file.";
	save();
}
sub save {
print RECORDS "$ref\n";
close(RECORDS);
}

Dave
 
at a very quick glance:-

Code:
#!c:\perl\bin\perl.exe

$records = "Data.txt";
if(-e $records) {
    open(RECORDS, "<Data.txt") or die "Could not open file.";
}
else {
    open(RECORDS, ">[blue][b]Data.txt[/b][/blue]") or die "Could not open file.";
    close(RECORDS);
}

print("Enter your four digit customer reference number.\n");
$ref=<STDIN>;
chomp($ref);

while ($ref!~m/^\d{4}$/)
    {
        print("Not a valid number, please enter your correct customer reference number.\n");
        $ref=<STDIN>;
    } 
$numExist = 0;
while(<RECORDS>) {
    # $numExist = 1;
        foreach($_){
        if($_=~m/^$ref/){
            print("$_");
            $numExist++;
            last;
        }
    }
}
if($numExist == 0) {
    open(RECORDS, ">>[red][b]Data.text[/b][/red]") or die "Could not open file.";
    save();
}
sub save {
print RECORDS "$ref\n";
close(RECORDS);
}


Kind Regards
Duncan
 
Another version just for fun.. :)

Code:
use strict;

my $dataFile = 'data.txt';

print "Enter your four digit customer reference number.\n";
chomp ( my $refNum = <STDIN> );

while ( $refNum !~ m/^\d{4}$/ ) {
    print("Not a valid number, please enter your correct customer reference number.\n");
    chomp($refNum = <STDIN>);
}

open( REC_IN, $dataFile ) or die "Couldn't open file: $!";

my @results;

while ( <REC_IN> ) {
        
    if (/^$refNum/) {
        push (@results, $refNum);
        last;
    }
}

close REC_IN;

if ( @results ) {
    print "$refNum already exists in $dataFile\n";
}
else {
    print "$refNum not found - appending to data file\n";
    open (REC_OUT,'>>',$dataFile) or die "Couldn't open file: $!";
    print REC_OUT "$refNum\n";
    close(REC_OUT);
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top