So I have a text file with four sets of data on a line, such as aa bb username password. So far I have been able to parse through the first line of the file using substrings and indices, and assigning each of the four to variables.
My goal is to use an array and chomp through each line and assign them to the four variables, and than to match an user inputted argument to the first variable, and use the four variables in that correct line.
For example, this would be the text file:
"aa bb cc dd"
"ee ff gg hh"
And depending on whether the user inputs "aa" or "ee" as the argument, it would use that line's set of arguments in the code.
I am trying to get up a basic array and chomp through it based on a condition for the first variable, essentially.
Here is my code for the four variables for the first line, but like I said, this only works for the first line in the text file:
local $/;
open(FILE, $configfile) or die "Can't read config file 'filename' [$!]\n";
my $document = <FILE>;
close (FILE);
my $string = $document;
my $substring = " ";
my $Index = index($string, $substring);
my $aa = substr($string, 0, $Index);
my $newstring = substr($string, $Index+1);
my $Index2 = index($newstring, $substring);
my $bb = substr($newstring, 0, $Index2);
my $newstring2 = substr($newstring, $Index2+1);
my $Index3 = index($newstring2, $substring);
my $cc = substr($newstring2, 0, $Index3);
my $newstring3 = substr($newstring2, $Index3+1);
my $Index4 = index($newstring3, $substring);
my $dd = substr($newstring3, 0, $Index4);
First of all, you can parse your whole line using split instead of running index and substring on them:
my ( $aa, $bb, $cc, $dd ) = split /\s+/, $line;
Even better, use an array:
my #array = split /\s+/, $line;
I think you're saying that you need to store each array of command parts into another array of lines. Is that correct? Take a look at this tutorial on references available in the Perl Documentation.
Perl has three different types of variables. The problem is that each of the types of variables of these stores only a single piece of data. Arrays and hashes may store lots of data, but only one piece of data can be stored in each element of a hash or array.
References allow you to get around this limitation. A reference is simply a pointer to another piece of data. For example, if $line = aa bb cc dd, doing this:
my #command_list = split /\s+/ $line;
Will give you the following:
$command_list[0] = "aa";
$command_list[1] = "bb";
$command_list[2] = "cc";
$command_list[3] = "dd";
You want to store #command_list into another structure. What you need is a reference to #command_list. To get a reference to it, you merely put a backslash in front of it:
my $reference = \#command_list;
This could be put into an array:
my #array;
$array[0] = $reference;
Now, I'm storing an entire array into a single element of an array.
To get back to the original structure from the reference, you put the correct sigil. Since this is an array, you put # in front of it:
my #new_array = #{ $reference };
If you want the first item in your reference without using having to transport it into another array, you could simply treat #{ $reference } as an array itself:
${ $reference }[0] = "aa";
Or, use the magic -> which makes the syntax a bit cleaner:
$reference->[0] = "aa";
Go through the tutorial. This will help you understand the full power of references, and how they can be used. Your program would look something like this:
use strict;
use warnings;
use feature qw(say); #Better print that print
use autodie; #Kills your program if the file can't be open
my $file = [...] #Somehow get the file you're reading in...
open my $file_fh, "<", $file;
my #command_list;
while ( my $line = <$file_fh> ) {
chomp $line;
my #line_list = split /\s+/, $line;
push #command_list, \#line_list;
}
Note that push #command_list, \#line_list; is pushing a reference to one array into another. How do you get it back out? Simple:
for my $cmd_line_ref ( #command_list ) {
my $command = $cmd_line_ref->[0]; #This is the first element in your command
next unless $command eq $user_desires; # However you figure out what the user wants
my $line = join " ", #{ $cmd_line_ref } #Rejoins your command line once again
??? #Profit
}
Read the tutorial on references, and learn about join and split.
You are reading the whole file in the my $document = <FILE> line.
Try something like:
my #lines;
open my $file, '<', $configfile or die 'xxx';
while( <$file> ) {
chomp;
push #lines, [ split ]
}
And now #lines has an array of arrays with the information you need.
(EDIT) don't forget to lose the local $/; -- it's what is making you read the whole file at once.
my $document = <FILE> is reading in only the first line. Try using a while loop.
If you want to read all lines of the file at once - assuming it's a small file - you may want to use File::Slurp module:
use File::Slurp;
my #lines = File::Slurp::read_file($configfile);
foreach my $line (#lines) {
# do whatever
Also, you can use CPAN modules to split the strings into fields.
If they are single-space separated, simply read the whole file using a standard CSV parser (you can configure Text::CSV_XS to use any characater as separator). Example here: How can I parse downloaded CSV data with Perl?
If they are separated by random amount of whitespace, use #massa's advice below and use split function.
Related
Suppose this is the file I am reading
hey how are you
I am fine thank you
Here I want to store the contents of file into an array using one while loop so that I can easily use the array later and need not to open close file again.
Code
use warnings;
use strict;
my #point1;
my #point ;
my $log1= "log1.log";
open(IN1, "<$log1" ) or die "Could not open file $log1: $!";
while (my $line = <IN1>) {
#point = split " ",$line;
push(#point1,#point);
push(#point1,"\n");
}
print "$point1[0] 2nd\n";
close IN1;
Output
hey 2nd
I want output like below if I am printing outside while loop.
Output I want:
hey 2nd
I 2nd
What changes should I make here?
You are pushing all the words in the file onto the same list, which will make it difficult to tell them apart.
push(#point1,#point);
This is the same as doing
#point1 = qw(hey how are you I am fine thank you);
I suspect what you want is a two-dimensional array, so that you afterwards can supply line number and word number and print that word, like this:
print $point1[0][0]; # prints "hey"
To do that, you would do this:
push #point1, \#point; # the backslash makes us get the reference to the array
But then you also have to make sure that all the lines do not point to the same array, as they would when you declare my #point outside of the loop.
my #point; # outside the loop
while (my $line = <IN1>) {
#point = split " ",$line;
push(#point1, \#point); # wrong
}
You would have to declare it inside the loop
while (my $line = <IN1>) {
my #point = split " ",$line; # inside the loop
push(#point1, \#point); # correct
}
Because then it will be a new array reference each loop iteration, one for each new line. But you do not need to use a temporary variable, you can just push the values directly
while (my $line = <IN1>) {
push #point1, [ split " ",$line; ];
}
The square brackets creates a reference to an anonymous array, with the values that are inside it. Afterward you can solve your task like this:
for my $aref (#point1) {
print "$aref->[0] 2nd\n";
}
Or
for my $line_no (0 .. $#point1) {
print "$point1[$line_no][0] 2nd\n";
}
use strict;
use warnings;
use feature qw( say );
my $log1 = "log1.log";
open(my $fh, "<", $log1) # Don't use a global. Use 3-arg open.
or die("Can't open file \"$log1\": $!\n"); # No need for the line number.
my #first_words;
while (my $line = <$fh>) {
# chomp($line); # Not needed with C<< split " " >>, so that was ok.
my #words = split " ", $line; # Declare variable to the scope where they are needed.
push #first_words, $words[0]; # You want the first word of each line.
}
for my $first_word (#first_words) { # Need a loop to print stuff repeatedly.
say "$first_word 2nd";
}
or
use strict;
use warnings;
use feature qw( say );
my #first_words;
while (my $line = <>) {
my #words = split " ", $line;
push #first_words, $words[0];
}
for my $first_word (#first_words) {
say "$first_word 2nd";
}
The second is more flexible. Just pass the desired file name as an argument. It can also handle input via STDIN.
It's not really clear what data structure you're looking for. Here are a few possibilities.
You want each line of your file in an element in the array.
my #array = <$fh>;
You want each line of your file in an element in the array, but you also want the input split into individual words (so you end up with an array of arrays).
my #array = map { [ split ] } <$fh>;
You want the first word of each line in an element in the array.
my #array = map { (split)[0] } <$fh>;
I've mentioned before that you should switch to using the three-arg version of open() and lexical filehandles. So, assume that all of my code examples above are prefaced with:
open my $fh, '<', $log1 or die "Cannot open '$log1': $!\n";
Looking back over your last few questions, I can't help thinking that this is an X/Y question. You're asking for our help with tiny problems that make up part of your code, but actually, we could give far better help if we knew more about the bigger picture.
I have written a script which collects marks of students and print the one who scored above 50.
Script is below:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my #array = (
'STUDENT1,90
STUDENT2,40
STUDENT3,30
STUDENT4,30
');
print Dumper(\#array);
my $class = "3";
foreach my $each_value (#array) {
print "EACH: $each_value\n";
my ($name, $score ) = split (/,/, $each_value);
if ($score lt 50) {
next;
} else {
print "$name, \"GOOD SCORE\", $score, $class";
}
}
Here I wanted to print data of STUDENT1, since his score is greater than 50.
So output should be:
STUDENT1, "GOOD SCORE", 90, 3
But its printing output like this:
STUDENT1, "GOOD SCORE", 90
STUDENT2, 3
Here some manipulation happens between 90 STUDENT2 which it discards to separate it.
I know I was not splitting data with new line character since we have single element in the array #array.
How can I split the element which is in array to new line, so that inside for loop I can split again with comma(,) to have the values in $name and $score.
Actually the #array is coming as an argument to this script. So I have to modify this script in order to parse right values.
As you already know your "array" only has one "element" with a string with the actual records in it, so it essentially is more a scalar than an array.
And as you suspect, you can split this scalar just as you already did with the newline as a separator instead of a comma. You can then put a foreach around the result of split() to iterate over the records.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $records = 'STUDENT1,90
STUDENT2,40
STUDENT3,30
STUDENT4,30
';
my $class = "3";
foreach my $record (split("\n", $records)) {
my ($name, $score) = split(',', $record);
if ($score >= 50) {
print("$name, \"GOOD SCORE\", $score, $class\n");
}
}
As a small note, lt is a string comparison operator. The numeric comparisons use symbols, such as <.
Although you have an array, you only have a single string value in it:
my #array = (
'STUDENT1,90
STUDENT2,40
STUDENT3,30
STUDENT4,30
');
That's not a big deal. Dave Cross has already shown you have you can break that up into multiple values, but there's another way I like to handle multi-line strings. You can open a filehandle on a reference to the string, then read lines from the string as you would a file:
my $string = 'STUDENT1,90
STUDENT2,40
STUDENT3,30
STUDENT4,30
';
open my $string_fh, '<', \$string;
while( <$string_fh> ) {
chomp;
...
}
One of the things to consider while programming is how many times you are duplicating the data. If you have it in a big string then split it into an array, you've now stored the data twice. That might be fine and its usually expedient. You can't always avoid it, but you should have some tools in your toolbox that let you avoid it.
And, here's a chance to use indented here docs:
use v5.26;
my $string = <<~"HERE";
STUDENT1,90
STUDENT2,40
STUDENT3,30
STUDENT4,30
HERE
open my $string_fh, '<', \$string;
while( <$string_fh> ) {
chomp;
...
}
For your particular problem, I think you have a single string where the lines are separated by the '|' character. You don't show how you call this program or get the data, though.
You can choose any line ending you like by setting the value for the input record separator, $/. Set it to a pipe and this works:
use v5.10;
my $string = 'STUDENT1,90|STUDENT2,40|STUDENT3,30|STUDENT4,30';
{
local $/ = '|'; # input record separator
open my $string_fh, '<', \$string;
while( <$string_fh> ) {
chomp;
say "Got $_";
}
}
Now the structure of your program isn't too far away from taking the data from standard input or a file. That gives you a lot of flexibility.
The #array contains one element, Actually the for loop will working correct, you can fix it without any change in the for block just by replacing this array:
my #array = (
'STUDENT1,90',
'STUDENT2,40',
'STUDENT3,30',
'STUDENT4,30');
Otherwise you can iterate on them by splitting lines using new line \n .
I want to able to read this CSV file into an array of arrays or hashes for manipulation. How can I go about it?
For example my file contains the following (the first line is the header):
Name,Age,Items,Available
John,29,laptop,mouse,Yes
Jane,28,desktop,keyboard,mouse,yes
Doe,56,tablet,keyboard,trackpad,touchpen,Yes
First column is name, second is Age, third is Items, But items can contain more than one thing separated by commas, and last column is Person availability.
How can I accurately read this?
Well-formed CSV quotes fields that contain a comma as part of the value. If your CSV is well-formed use the Text::CSV module:
use Text::CSV;
my $csv = Text::CSV->new();
while (my $row = $csv->getline(\*DATA)) {
my $name = $row->[0];
my $age = $row->[1];
my #items = split /,/, $row->[2];
my $available = $row->[3];
print "$name/$age/#items/$available\n";
}
__DATA__
Name,Age,Items,Available
John,29,"laptop,mouse",Yes
Jane,28,"desktop,keyboard,mouse",yes
Doe,56,"tablet,keyboard,trackpad",touchpen,Yes
Output:
Name/Age/Items/Available
John/29/laptop mouse/Yes
Jane/28/desktop keyboard mouse/yes
Doe/56/tablet keyboard trackpad touchpen/Yes
If your CSV is not well-formed you'll need to implement a custom parse based on knowledge of your data. Assuming that the Items column is the only multi-valued field you can split on a comma and then remove the fields with a known position. Whatever is left is the items.
while (my $line = <DATA>) {
chomp $line;
my #record = split /,/, $line;
my $name = shift #record;
my $age = shift #record;
my $available = pop #record;
my #items = #record;
print "$name/$age/#items/$available\n";
}
__DATA__
Name,Age,Items,Available
John,29,laptop,mouse,Yes
Jane,28,desktop,keyboard,mouse,yes
Doe,56,tablet,keyboard,trackpad,touchpen,Yes
Alternately, you could use array slicing to get the same result:
my ($name, $age, $available, #items) = #record[0, 1, -1, 2 .. #record - 2];
Since your data is, in reality, a properly-formatted CSV file, you can use the standard tools to read and store it
Here's the data I'm now assuming that you have
Name,Age,Items,Available
John,29,"laptop,mouse",Yes
Jane,28,"desktop,keyboard,mouse",yes
Doe,56,"tablet,keyboard,trackpad,touch pen",Yes
Solution
Like my original answer, this code uses Text::CSV to parse each line of input. But instead of having to reformat it, each row may be pushed directly onto array #data
Also as before, it conforms to the standard of reading from STDIN. But this time I have used Data::Dump to reveal the in-memory data structure that has been built. If you run it on the command line you should use
$ perl unpack_csv.pl text.csv
use strict;
use warnings 'all';
use Text::CSV;
my $csv = Text::CSV->new;
my #data;
while ( <> ) {
$csv->parse($_);
my #row = $csv->fields;
push #data, \#row;
}
use Data::Dump;
dd \#data;
Update
I now realise that the OP's file may well contain properly-formatted CSV data, which makes this answer superfluous
However the question has not been changed to show the real data, so I am leaving this answer here in case the question's subject line and content entices people with a problem that this will solve
I recommend that you use an intermediate program to format your CSV file properly. Once you have a standard-format file, the resulting output can then be processed using Perl with Text::CSV, Excel, or anything similar
This program uses Text::CSV to read your input data and write the Items column enclosed in quotes if necessary
It works by using Text::CSV->parse to split each line into fields, and then reserving the first two and final fields for new fields 1, 2 and 4. Whatever is left is joined with a comma , and used for field 3. The four resulting values are passed back to Text::CSV->combine and printed
It conforms to the standard of reading from STDIN and writing to STDOUT, so if you run it on the command line you should use
$ perl reformat_csv.pl text.csv > new_text.csv
use strict;
use warnings 'all';
use Text::CSV;
my $csv = Text::CSV->new;
while ( <> ) {
$csv->parse($_);
my #row = $csv->fields;
my $f1 = shift #row;
my $f2 = shift #row;
my $f4 = pop #row;
my $f3 = join ',', #row;
$csv->combine($f1, $f2, $f3, $f4);
print $csv->string, "\n";
}
output
Name,Age,Items,Available
John,29,"laptop,mouse",Yes
Jane,28,"desktop,keyboard,mouse",yes
Doe,56,"tablet,keyboard,trackpad,touchpen",Yes
Firstly I apologise if my formatting here is incorrect, I am very new to writing scripts (3 days) and this is my first post on this site.
I have two files which are tab separated, File a contains 14 columns, and File b contains 8 columns.
One column in File b has a numeric value which correlates to a range of numbers generated by two numeric fields from File a.
For every line in File a, I need to, search through the File b and print a combination of data from fields on both files. There will be multiple matches for each line of File a due to a numeric range being accepted.
The code that I have created does exactly what I want it to do but only for the first line of File a, and doesn't continue the loop. I have looked all over the internet and I believe it may be something to do with the fact that both files read from standard input. I have tried to correct this problem but I can't seem to get anything to work
My current understanding is that by changing one file to read from a different file descriptor my loop may work... with something such as >$3 but I don't really understand this very well despite my research. Or possibly using the grep function which I am also struggling with.
Here is the outline of the code I am using now:
use strict;
use warnings;
print "which file read from?\n";
my $filea = <STDIN>;
chomp $filea;
{
unless (open ( FILEA, $filea) {
print "cannot open, do you want to try again? y/n?\n?";
my $attempt = <STDIN>;
chomp $again;
if ($again =~ 'n') {
exit;
} else {
print "\n";
$filea = <STDIN>;
chomp $filea;
redo;
}
}
}
#I also open fileb the same way, but wont write it all out to save space and your time.
my output = 'output.txt';
open (OUTPUT, ">>$output");
while (my $loop1 = <FILEA>) {
chomp $loop1;
( my $var1, my $var2, my $var3, my $var4, my $var5, my $var6,
my $var7, my $var8, my $var9, my $var10, my $var11, my $var12,
my $var13, my $var14 ) = split ( "\t", $loop1);
#create the range of number which needs to be matched from file b.
my $length = length ($var4);
my $range = ($var2 + $length);
#perform the search loop through fileb
while (my $loop2 = <FILEB>) {
chomp $loop2;
( my $vala, my $valb, my $valc, my $vald, my $vale, my $valf,
my $valg) = split ( "\t", $loop2 );
#there are then several functions and additions of the data, which all work basicly so I'll just use a quick example.
if ($vald >= $val3 $$ $vald <= $range) {
print OUTPUT "$val1, $vald, $val11, $valf, $vala, $val5 \n";
}
}
}
I hope this all makes sense, I tried to make everything as clear as possible, if anyone could help me edit the code so that the loop continues through all of filea that would be great.
If possible please explain what you've done. Ideally I'd like it if its possible to obtain this result without changing the code too much.
Thanks guys!!!
Avoid naked handles when possible; use $fh (filehandle) instead of FH
You can use until instead of unless, and skip the redo:
print "Enter the file name\n";
my $file_a = <STDIN>;
chomp $file_a;
my $fh_a;
until(open $fh_a, '<', $file_a) {
print "Re-enter the file name or 'n' to cancel\n";
$file_a = <STDIN>;
chomp $file_a;
if($file_a eq 'n') {
exit;
}
}
You can (should) use an array instead of all those individual column variables: my #cols_a = split /\t/, $line;
You should read file B into an array, once, and then search that array each time you need to: my #file_b = <$fh_b>;
The result will look something like this:
#Assume we have opened both files already . . .
my #file_b = <$fh_b>;
chomp #file_b;
while(my $line = <$fh_a>) {
chomp $line;
my #cols_a = split /\t/, $line;
#Remember, most arrays (perl included) are zero-indexed,
#so $cols_a[1] is actually the SECOND column.
my $range = ($cols_a[1] + length $cols_a[3]);
foreach my $line_b (#file_b) {
#This loop will run once for every single line of file A.
#Not efficient, but it will work.
#There are, of course, lots of optimisations you can make
#(starting with, for example, storing file B as an array of array
#references so you don't have to split each line every time)
my #cols_b = split /\t/, $line_b;
if($cols_b[3] > $cols_a[2] && $cols_b[3] < ($cols_a[2] + $range)) {
#Do whatever here
}
}
}
am very new to Perl and need your help
I have a CSV file xyz.csv with contents:
here level1 and er values are strings names...not numbers...
level1,er
level2,er2
level3,er3
level4,er4
I parse this CSV file using the script below and pass the fields to an array in the first run
open(my $d, '<', $file) or die "Could not open '$file' $!\n";
while (my $line = <$d>) {
chomp $line;
my #data = split "," , $line;
#XYX = ( [ "$data[0]", "$data[1]" ], );
}
For the second run I take an input from a command prompt and store in variable $val. My program should parse the CSV file from the value stored in variable until it reaches the end of the file
For example
I input level2 so I need a script to parse from the second line to the end of the CSV file, ignoring the values before level2 in the file, and pass these values (level2 to level4) to the #XYX = (["$data[1]","$data[1]"],);}
level2,er2
level3,er3
level4,er4
I input level3 so I need a script to parse from the third line to the end of the CSV file, ignoring the values before level3 in the file, and pass these values (level3 and level4) to the #XYX = (["$data[0]","$data[1]"],);}
level3,er3
level4,er4
How do I achieve that? Please do give your valuable suggestions. I appreciate your help
As long as you are certain that there are never any commas in the data you should be OK using split. But even so it would be wise to limit the split to two fields, so that you get everything up to the first comma and everything after it
There are a few issues with your code. First of all I hope you are putting use strict and use warnings at the top of all your Perl programs. That simple measure will catch many trivial problems that you could otherwise overlook, and so it is especially important before you ask for help with your code
It isn't commonly known, but putting a newline "\n" at the end of your die string prevent Perl from giving file and line number details in the output of where the error occurred. While this may be what you want, it is usually more helpful to be given the extra information
Your variable names are verly unhelpful, and by convention Perl variables consist of lower-case alphanumerics and underscores. Names like #XYX and $W don't help me understand your code at all!
Rather than splitting to an array, it looks like you would be better off putting the two fields into two scalar variables to avoid all that indexing. And I am not sure what you intend by #XYX = (["$data[1]","$data[1]"],). First of all do you really mean to use $data[1] twice? Secondly, your should never put scalar variables inside double quotes, as it does something very specific, and unless you know what that is you should avoid it. Finally, did you mean to push an anonymous array onto #XYX each time around the loop? Otherwise the contents of the array will be overwritten each time a line is read from the file, and the earlier data will be lost
This program uses a regular expression to extract $level_num from the first field. All it does it find the first sequence of digits in the string, which can then be compared to the minimum required level $min_level to decide whether a line from the log is relevant
use strict;
use warnings;
my $file = 'xyz.csv';
my $min_level = 3;
my #list;
open my $fh, '<', $file or die "Could not open '$file' $!";
while (my $line = <$fh>) {
chomp $line;
my ($level, $error) = split ',', $line, 2;
my ($level_num) = $level =~ /(\d+)/;
next unless $level_num >= $min_level;
push #list, [ $level, $error ];
}
For deciding which records to process you can use the "flip-flop" operator (..) along these lines.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my $level = shift || 'level1';
while (<DATA>) {
if (/^\Q$level,/ .. 0) {
print;
}
}
__DATA__
level1,er
level2,er2
level3,er3
level4,er4
The flip-flop operator returns false until its first operand is true. At that point it returns false until its second operand is true; at which point it returns false again.
I'm assuming that your file is ordered so that once you start to process it, you never want to stop. That means that the first operand to the flip-flop can be /^\Q$level,/ (match the string $level at the start of the line) and the second operand can just be zero (as we never want it to stop processing).
I'd also strongly recommend not parsing CSV records using split /,/. That may work on your current data but, in general, the fields in a CSV file are allowed to contain embedded commas which will break this approach. Instead, have a look at Text::CSV or Text::ParseWords (which is included with the standard Perl distribution).
Update: I seem to have got a couple of downvotes on this. It would be great if people would take the time to explain why.
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
my #XYZ;
my $file = 'xyz.csv';
open my $fh, '<', $file or die "$file: $!\n";
my $level = shift; # get level from commandline
my $getall = not defined $level; # true if level not given on commandline
my $parser = Text::CSV->new({ binary => 1 }); # object for parsing lines of CSV
while (my $row = $parser->getline($fh)) # $row is an array reference containing cells from a line of CSV
{
if ($getall # if level was not given on commandline, then put all rows into #XYZ
or # if level *was* given on commandline, then...
$row->[0] eq $level .. 0 # ...wait until the first cell in a row equals $level, then put that row and all subsequent rows into #XYZ
)
{
push #XYZ, $row;
}
}
close $fh;
#!/usr/bin/perl
use strict;
use warnings;
open(my $data, '<', $file) or die "Could not open '$file' $!\n";
my $level = shift ||"level1";
while (my $line = <$data>) {
chomp $line;
my #fields = split "," , $line;
if($fields[0] eq $level .. 0){
print "\n$fields[0]\n";
print "$fields[1]\n";
}}
This worked....thanks ALL for your help...