Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 248
  • Last Modified:

Reading from a file - by passing the value

Hi ,
I am writing data from into a file. This file is pipe demilited and every new data starts from a new line. First value of the line is unique value. I need to read this file and generate a report. Now my question is -

If i am having this file ready then how can i read the data by passing that unique key.

Format of the file is like this ->
12345|Tom|Jonh|Analyst|Software devision|$30000|5 Years|contract expires on 2132|end
-----------------------------------------------------------------
-----------------------------------------------------------------
------------------------------------------------------------------

Now i will pass the 12345 to this file to take the rest of the data i.e Tom , John , Analyst etc. in the same order which will be printed in another report.

Thanks in Advance !

Aaku
0
akku_batra
Asked:
akku_batra
  • 4
  • 2
  • 2
  • +2
2 Solutions
 
PurplePerlsCommented:
On windows do it like this:

type customer.dat | perl extract.pl 12346

Where the extract.pl is like this:

my $key = shift;
while (<>) {
  print unless !(/^$key/);
}


On Unix it is simelar command:
cat customer.dat | perl extract.pl 12346 >> report.dat




0
 
PurplePerlsCommented:
And if you like to remove the key and change the pipes to comas, then try this:

my $key = shift;
while (<>) {
  if(/^$key/){
    $_ =~ s/^\w+\|//;
    $_ =~ s/\|/\,/g;
    print;
  };
};



0
 
ozoCommented:
Better to use
/^$key\|/
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
PurplePerlsCommented:
That's very true!
Worst case if , no key is entered, then are all records returned.

Here the corrected version:

my $key = shift;
while (<>) {
  if(/^$key\|/){
    $_ =~ s/^\w+\|//;
    $_ =~ s/\|/\,/g;
    print;
  };
};


Or without normalization:
my $key = shift;
while (<>) {
  print unless !(/^$key\|/);
}

0
 
kanduraCommented:
In that last bit i'd change the double negative from

   print unless !(/^$key\|/);

to

   print if /^$key\|/;

I never didn't like no double negatives ;^)
0
 
kanduraCommented:
Another note: if the file isn't too big (say, under 10MB), and you'd like to report on more than just a single line, then it may be easier to just slurp the whole file into a hash, where the keys are your unique first values, and the value is the rest of the line (possibly you'd even want the rest of the line split into an array as well, which I'll show too):

#!/usr/bin/perl -w

my $filename = 'data.txt';
my %lines = ();

open F, $filename or die $!;
while(<F>)
{
  chomp;                                             # remove newline
  my ($key, $data) = split /\|/, $_, 2;     # split on | into two parts
  $lines{$key} = $data;

  ### alternatively, store an array ref to the data
  my ($key, @flds) = split /\|/, $_;
   $lines{$key} = \@flds;
}
close F;

### now use %lines
my @somekeys = qw( 12345 12346 );   # some random keys ;^)
foreach(@somekeys)
{
    print $lines{$_}, "\n";
   
   ### alternatively
    print join(', ', @{$lines{$_}}), "\n";
}

0
 
ozoCommented:
#Another way to use a hash without using up space on large files is:
my $filename = 'data.txt';
my @somekeys = qw( 12345 12346 );   # some random keys ;^)
@hash{@somekeys} = (1)x@somekeys;

open F, $filename or die $!;
while( <F> ){
  my ($key, $data) = split /\|/, $_, 2;     # split on | into two parts
  print if $hash{$key};
close F;
0
 
TintinCommented:
PurplePerls.

No need to fork additional processes:

cat customer.dat | perl extract.pl 12346 >> report.dat

is better written as

perl extract.pl 12346 <customer.dat >> report.dat

No UUOC
0
 
PurplePerlsCommented:
Thanks.
Now I learned one more jargon acronym :)
0
 
jmcgOwnerCommented:
Nothing has happened on this question in more than 6 weeks. It's time for cleanup!

My recommendation, which I will post in the Cleanup topic area, is to
split points between PurplePerls and ozo.

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 4
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now