bladx has asked for the wisdom of the Perl Monks concerning the following question:
hi!
I am currently working on a project that will eventually be used for the internet mainly. Anyways, I am really stuck with trying to figure out the following question:
I have a flatfile database with a text file. What I want a certain subroutine to do is to find out how many lines first of all are in the text file, ( with \n being the divider of lines,) and then with each individual line, break up each thing of information (seperated by '|') and I can't figure out how to do that second step! I need it to be able to figure out how many variables it needs to make for each line and individual info. It would be great if anyone could help me figure out a way to do this!!
thanks a bunch!
Andy
Re: Getting info with a small flatfile db.
by chromatic (Archbishop) on Aug 03, 2001 at 09:37 UTC
|
The simple command for the second step is split. Of course, depending on how complex the data is (whether the pipe character can be escaped and included in a field), you might have better luck with Text::CSV, Text::xSV, or even DBD::CSV. They should be ordered there by relative complexity.
Counting lines in a file is pretty easy, too. You can slurp them all into an array (if the file is small) and evaluate the array in scalar context. Otherwise, you can loop through the entire file, line by line, and use the special variable $.. The modules named above may have their own mechanisms for doing this.
Update: Stuff the results into an array, that way you won't have to worry about it. Otherwise, you can count the number of pipes in a line with the simple:
my $numpipes = $line =~ tr/\|//; | [reply] [Watch: Dir/Any] [d/l] |
|
Thank you, but I already am using the split command, and what I really need is for it to be able to figure out how many variables it needs to put data into per line. any help?
Andy
| [reply] [Watch: Dir/Any] |
|
There are a bunch of different ways: count the number of pipes in the line, and add one. You can use tr/|// for this (returns the number of |s).
Second way store the results from split in an array:
my @parts = split /\|/, $line;
Perl will grab all the bits there are to grab. As chromatic mentioned, you can evaluate that array in scalar context to find out how many parts there are. You can also use a list assignment to nab, say, only the first five:
my ($first, $second, $third, $fourth, $fifth, undef) = split /\|/, $st
+ring,6;
HTH
perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>);
+$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth
+er_name\n"'
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Getting info with a small flatfile db.
by thatguy (Parson) on Aug 03, 2001 at 09:45 UTC
|
you don't need the line number to access the info in your db, but this should work for you. use strict;
use vars qw/ $lines $blah1 $blah2 $blah3 /;
sub count_lines {
$lines = 0;
open(FILE, "filename");
while(<FILE>) {
$lines += ($_ =~ tr/\n//);
}
print "$lines lines in filename\n";
close (FILE);
}
sub breakup_lines {
open(FILE, "filename");
while(<FILE>) {
($blah1,$blah2,$blah3) = split(/\|/, $_);
## do something with the blahs
}
close (FILE);
}
also you may want to check out these nodes: Another flatfile thingy & Poor Person's Database and how could we forget the Super Search? Update: I see you don't know how many columns you are going to have. so instead use sub breakup_lines {
open(FILE, "filename");
while(<FILE>) {
push @blah, (split /\|/);
## do something with the @blah
}
close (FILE);
}
.then you can do whatever with @blah (oh and add @blah to the vars statement at the top.) -p | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Getting info with a small flatfile db.
by snowcrash (Friar) on Aug 03, 2001 at 09:49 UTC
|
hi!
as usually, there are quite a lot of ways to do it. although
you could write the code for parsing a individual line
yourself, using split or regular expressions, i would
recommend to use a module like Text::CSV_XS that does the
work for you.
some sample code could look like this:
use Text::CSV_XS;
my $csv = Text::CSV_XS->new({
'quote_char' => '"',
'escape_char' => '"',
'sep_char' => '|',
'binary' => 1
});
while my $line (<YOURFILE>) {
if ($csv->parse($line)) {
my @field = $csv->fields;
my $count = 0;
for $column (@field) {
print ++$count, " => ", $column, "\n";
}
print "\n";
} else {
my $err = $csv->error_input;
print "parse() failed on argument: ", $err, "\n";
}
}
snowcrash ////// | [reply] [Watch: Dir/Any] [d/l] |
Re: Getting info with a small flatfile db.
by Zaxo (Archbishop) on Aug 03, 2001 at 09:42 UTC
|
See perldoc perlfunc for open, close, split and scalar, then perldoc perlop for the diamond operator, <>.
Update: You don't need seperate variables for the db line fields, split returns an array: my @ary = split /\|/;
After Compline, Zaxo
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Getting info with a small flatfile db.
by JP Sama (Hermit) on Aug 03, 2001 at 20:10 UTC
|
you could use "\t" instead of "|"...
IMHO...
#!/jpsama/bin/perl -w
$tks = `mount`;
$jpsama = $! if $!;
print $jpsama;
| [reply] [Watch: Dir/Any] |
|
|