Operating System - HP-UX
1830256 Members
2052 Online
110000 Solutions
New Discussion

Need to upgrade a perl script

 
Steven E. Protter
Exalted Contributor

Need to upgrade a perl script

For oracle admins, I want to read the first database instance out of /etc/oratab and nothing else.

Here is the code snipped...

$oratab='/etc/oratab';

open (ORATAB,"$oratab");
@filedata = ;
foreach $filedata (@filedata){
chop ($filedata) if ($filedata =~/\n$/);
# chop ($filedata) if ($filedata =~/:/);

$filetoback = $filedata;
print "${filetoback}\n";
};
close (ORATAB);


Here is the output

# This file is used by ORACLE utilities. It is created by root.sh
# and updated by the Database Configuration Assistant when creating
# a database.

# A colon, ':', is used as the field terminator. A new line terminates
# the entry. Lines beginning with a pound sign, '#', are comments.
#
# Entries are of the form:
# $ORACLE_SID:$ORACLE_HOME::
#
# The first and second fields are the system identifier and home
# directory of the database respectively. The third filed indicates
# to the dbstart utility that the database should , "Y", or should not,
# "N", be brought up at system boot time.
#
# Multiple entries with the same $ORACLE_SID are not allowed.
#
#
#
jufsys:/oracle/product/8.1.7:Y
*:/ias/product/1.0.2/6iserver:N


I need that jufsys part before the colon, nothing more. I want to ignore the comments.

I look at the chop statement and see a \n and think its reading util it gets a newline character.

Can anyone suggest a snippet that will do what I want?

As always, points awarded liberally.

Steve
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com
9 REPLIES 9
Ralph Grothe
Honored Contributor

Re: Need to upgrade a perl script

Hi Steve,

though you'd better do it in a loop if it were a large file (> 1000 lines) I guess usually the oratab files don't tend to become that large.
Thus, attached you may find a more "idiomatic" version that builds a hash of the entries in a single statement.
I think the Perlians prefer to make it look like line noise ;-)

Just substitute the DATA handle with your handle.

n.b. just an advise (the Perlians are picky about this), do get into the habit to

use strict
use warnings # if you have Perl >= 5.6
# else -w
and always check success after open()
Madness, thy name is system administration
Ralph Grothe
Honored Contributor

Re: Need to upgrade a perl script

Maybe this was far too obfuscated.
It's always better to process a file by line as it safes memory.
The usual idiom is to read a line by the diamond operator (aka readline operator) in a while loop and parse this.
Remember that the diamond operator either gets a single line if used in scalar context,
or else (as we both used it) in list context dumps the whole stuff in an array (very wasteful)

e.g.

use constant ORATAB => '/etc/oratab';
local *FH;
my @sids;
open FH, ORATAB or die "cannot open file: $!\n";
while (defined (my $line = )) {
next if /^#/; # discard comments
next if /^\s+$/; discard blank lines
chomp; # chops off what is in $/
push @sids, (split /\:/, $line)[0];
}
close FH;


Now all the SIDs should be in the array @sids (I just typed it without checking)

If you don't like splitting you could also use a regex with backtracking (which I guess is a bit less efficient)

e.g.

$line =~ /(\w+?):.*/;
push @sids, $1;

(hope I haven't made a mistake, you should check it first)
Madness, thy name is system administration
Ralph Grothe
Honored Contributor

Re: Need to upgrade a perl script

How embarrassing, there were some flaws.
I relied on the magic varaible $_ (which usually is a bad thing) where I should use my introduced $line variable.

So it must of course be

next if $line =~ /^#/;
next if $line =~ /^\s+$/;

Madness, thy name is system administration
H.Merijn Brand (procura
Honored Contributor

Re: Need to upgrade a perl script

With recent perls, also prevent using localized globs, but instead use lexical file handles. Here's Ralph's code rewritten

open my $ot, "my @sids = grep s/^(\S+):.*/$1/s, <$ot>;
close $ot;

just a tiny bit shorter :)
Enjoy, Have FUN! H.Merijn
Steven E. Protter
Exalted Contributor

Re: Need to upgrade a perl script

For being so kind as to reply, everyone gets five points. We lost our LAN on Saturday and I can't test the fix until Monday. Anyone whose code gets used gets upgraded to 10 points, even if that multiple people.

Please check back, in case I have questions. A good lecture on how those arcane little filters work would be very useful and worth another 10 points.

Thanks.
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com
Steven E. Protter
Exalted Contributor

Re: Need to upgrade a perl script

itrc won't let me add points.

I have used Ralph's two posts to build a working script.

Thanks.

Do a happy new year post and I'll pile on another 10 spot.

Steve
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com
Avi Liani
Occasional Contributor

Re: Need to upgrade a perl script

Hello,

if you whant to ignore the comments do this :

open (ORATAB,"$oratab");
@filedata = ;
foreach $filedata (@filedata){
chop ($filedata) if ($filedata =~/\n$/);
# chop ($filedata) if ($filedata =~/:/);

if ($filedata !~ /^#/) {
$filetoback = $filedata;
print "${filetoback}\n";
}

};
close (ORATAB);



avili
H.Merijn Brand (procura
Honored Contributor

Re: Need to upgrade a perl script

Happy new year :) [ You can't get them cheaper ]


Avi, don't use

chop if m/\n$/;

that is depricated, and much better done as

chomp;

chomp is a safe and repeatable way of clipping line endings - accross systems, so \r\n, \r, \n are all valid (think MacOS) - and chop's only if the line ending is present. Why is it faster, you'd ask? Because it is implemented in the internals. Perl scripts' speed depend on the number of OP's a deparsed script generates:

a5:/pro/3gl/CPAN/perl-current/pod 122 > perl -MO=Terse -e 'chop if /\n$/' 1
LISTOP (0x40021bb0) leave [1]
OP (0x4002af38) enter
COP (0x4002aef0) nextstate
UNOP (0x40021b80) null
LOGOP (0x4001e138) and
PMOP (0x4001e048) match /\n$/
UNOP (0x4001e000) schop [2]
UNOP (0x4001dfd0) null [15]
SVOP (0x4001dfa0) gvsv GV (0x4001a304) *_
-e syntax OK
a5:/pro/3gl/CPAN/perl-current/pod 123 > perl -MO=Terse -e 'chomp' 1
LISTOP (0x4001e078) leave [1]
OP (0x4001e0a8) enter
COP (0x4001e030) nextstate
UNOP (0x4001e000) schomp [2]
UNOP (0x4001dfd0) null [15]
SVOP (0x4001dfa0) gvsv GV (0x4001a304) *_
-e syntax OK
a5:/pro/3gl/CPAN/perl-current/pod 124 >
Enjoy, Have FUN! H.Merijn
Steven E. Protter
Exalted Contributor

Re: Need to upgrade a perl script

Gentlemen, you are great.

Steve
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com