CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
removing all lines that contain the asterisk

 



goudeuk
Novice

May 2, 2014, 8:26 AM

Post #1 of 15 (6468 views)
removing all lines that contain the asterisk Can't Post

Hello everyone

I am trying to extract a list of users from passwd using awk. All I want is
their username and full name. Some of the lines contain the asterisk symbol
which I need to get them out of my output.

I can grab the name and fullname like this:

awk -F: '{print $1,$5}' < passwd.global

but how can I not include the lines that contain the asterisk symbol from my output?

Any suggestions please
Many thanks for your help


FishMonger
Veteran / Moderator

May 2, 2014, 8:46 AM

Post #2 of 15 (6460 views)
Re: [goudeuk] removing all lines that contain the asterisk [In reply to] Can't Post

How is this related to Perl?


goudeuk
Novice

May 2, 2014, 8:47 AM

Post #3 of 15 (6458 views)
Re: [FishMonger] removing all lines that contain the asterisk [In reply to] Can't Post

Is it not?


FishMonger
Veteran / Moderator

May 2, 2014, 9:12 AM

Post #4 of 15 (6446 views)
Re: [goudeuk] removing all lines that contain the asterisk [In reply to] Can't Post


In Reply To
Is it not?

awk is not Perl.

Did you want a Perl solution to replace your awk command?


goudeuk
Novice

May 2, 2014, 9:19 AM

Post #5 of 15 (6441 views)
Re: [FishMonger] removing all lines that contain the asterisk [In reply to] Can't Post

Well eventually I am planning to call the awk command from a perl script
using: system("awk -F: '{print $1,$5}' < passwd.global");

but if it's easier for you to do it in Perl then yes please do.


Laurent_R
Veteran / Moderator

May 2, 2014, 9:59 AM

Post #6 of 15 (6431 views)
Re: [goudeuk] removing all lines that contain the asterisk [In reply to] Can't Post

Yes, don't call awk from a Perl script, Perl can do everything awk can do and much more (and usually more efficiently).

This is a one-liner to filter out lines with an asterisk:

Code
perl -ne 'print unless /\*/; ' source_file.txt



FishMonger
Veteran / Moderator

May 2, 2014, 10:14 AM

Post #7 of 15 (6427 views)
Re: [goudeuk] removing all lines that contain the asterisk [In reply to] Can't Post

Calling awk from perl doesn't make any sense since perl can do it all.

In perl there are multiple ways to accomplish this task. Some are quick, dirty and sloppy (I'm not putting Laurent's solution in the dirty/sloppy side), which I normally refuse to do. Others are more robust, readable and maintainable which is what I prefer.

Open a filehandle and read the file line-by-line and process each line as needed skipping over the lines that you don't want.

You haven't said what the real goal is but I'd probably load the desired data into a hash for additional processing as needed.

This example meets the requirement and is between the 2 extremes (but leans toward the robust side).

Code
my $file = 'passwd.global'; 
open my $fh, '<', $file or die "failed to open '$file' <!>";
while ( <$fh> ) {
my ($user, $name) = (split /:/)[0,4];
print "$user\t$name\n" unless $user =~ /\*/;
}
close $fh;



(This post was edited by FishMonger on May 2, 2014, 10:16 AM)


goudeuk
Novice

May 6, 2014, 1:48 AM

Post #8 of 15 (6253 views)
Re: [FishMonger] removing all lines that contain the asterisk [In reply to] Can't Post

Many thanks to both of you for providing a solution to my problem.Smile

I prefer fishmonger's solution but they both work great.

Thank you


(This post was edited by goudeuk on May 6, 2014, 1:49 AM)


goudeuk
Novice

May 9, 2014, 8:02 AM

Post #9 of 15 (5807 views)
Re: [FishMonger] removing all lines that contain the asterisk [In reply to] Can't Post

Hi fishmonger

I am trying to save the output to a new file like this:


Code
my $file = 'passwd.global';  
open my $fh, '<', $file or die "failed to open '$file' <!>";
while ( <$fh> ) {
my ($user, $name) = (split /:/)[0,4];
print $fh "$user\t$name\n" unless $user =~ /\*/;
}
close $fh;


Code
 
But I can't get it work. Could you please let me know how can I save the output into passwd.global or in a newly created file?
Or direct me to a relative tutorial.

Many thanks for your help


(This post was edited by goudeuk on May 9, 2014, 8:06 AM)


FishMonger
Veteran / Moderator

May 9, 2014, 9:00 AM

Post #10 of 15 (5778 views)
Re: [goudeuk] removing all lines that contain the asterisk [In reply to] Can't Post

You need to open another filehandle to a NEW file and write the data to that new file.

Once that is complete, close the filehandles, delete the 'passwd.global' file and rename the newly created file to 'passwd.global'.


(This post was edited by FishMonger on May 9, 2014, 9:01 AM)


goudeuk
Novice

May 12, 2014, 1:55 AM

Post #11 of 15 (4372 views)
Re: [FishMonger] removing all lines that contain the asterisk [In reply to] Can't Post

Thanks Fishmonger

I tried the following:


Code
my $pwdfile = '/home/perl/files/passwd1.csv'; 
my $list = '/home/perl/list.txt';
my ($FH, $FH2, $username, $password, $fullname);



open $FH , '<', $pwdfile || die "Can't read: '$pwdfile' $!\n";

while (<$FH>)
{
($username,$password,$fullname) = (split /:/)[0,1,4];
print $FH "$username\t$fullname\n" unless $password =~ /\*/ ;
}
close $FH;

open $FH2, '+>', $list || die "Can't write: '$list' $!\n";

print $FH2 $FH;
close $FH2;


Code
 
But my output is: GLOB(0x1d6da68). I think I did what you described in your previous post. I opened one file handle for reading the file, the closed it and then opened a new one to write the changes.


(This post was edited by goudeuk on May 12, 2014, 2:43 AM)


goudeuk
Novice

May 12, 2014, 3:21 AM

Post #12 of 15 (4334 views)
Re: [goudeuk] removing all lines that contain the asterisk [In reply to] Can't Post

Hello again,

I managed to do it, thanks to fishmonger's mini how-to.
here is the result:


Code
my $pwdfile = '/home/perl/ad/passwd1.csv'; 
my $list = '/home/perl/ad/list.txt';

my ($FH1, $FH2, $username, $password, $fullname);


open $FH1, '<', $pwdfile || die "Can't read: '$pwdfile' $!\n";
open $FH2, '>', $adlist || die "Can't write: '$list' $!\n";

while (<$FH1>)
{
($username,$password,$fullname) = (split /:/)[0,1,4];
print $FH2 "$username\t$fullname\n" unless $password =~ /\*/ ;
}
close (FH1) || die "can't close $FH1: $!";
close (FH2) || die "can't close $FH2: $!";

rename ($FH1, "$FH1.orig") or die "can't rename $FH1 to $FH1.orig: $!";
rename($FH2, $FH1) or die "can't rename $FH2 to $FH1: $!";

Code
 
But because I am using warnings, stricts and diangostics, I get this warning message when I run it:

Name "main::FH1" used only once: possible typo at userlist.pl line 22 (#1)
(W once) Typographical errors often show up as unique variable names.
If you had a good reason for having a unique name, then just mention it
again somehow to suppress the message. The our declaration is
provided for this purpose.

NOTE: This warning detects symbols that have been used only once so $c, @c,
%c, *c, &c, sub c{}, c(), and c (the filehandle or format) are considered
the same; if a program uses $c only once but also uses any of the others it
will not trigger this warning.

Name "main::FH2" used only once: possible typo at userlist.pl line 23 (#1)
Uncaught exception from user code:
can't close GLOB(0xf57a68): Bad file descriptor at aduserlist.pl line 22, <$FH1> line 2400.


BillKSmith
Veteran

May 12, 2014, 5:44 AM

Post #13 of 15 (4270 views)
Re: [goudeuk] removing all lines that contain the asterisk [In reply to] Can't Post

Did you look for errors in lines 22 and 23? You forgot to fix these lines when you changed to lexical file handles.


Code
close ($FH1) || die "can't close $pwdfile: $!";  
close ($FH2) || die "can't close $adlist: $!";


The last error message is from your own die "...". You got the GLOB because you used the file handle rather than the file name in call to die.

You made the same error four more times in rename. Perl did not tell you about this because it did not get that far. (It died at the first close)
Good Luck,
Bill


goudeuk
Novice

May 12, 2014, 6:10 AM

Post #14 of 15 (4259 views)
Re: [BillKSmith] removing all lines that contain the asterisk [In reply to] Can't Post

Thank you BillKSmith.

I corrected the mistakes and there are no warnings or GLOB errors anymore.

Many thanks for your time and reply.
Smile


Laurent_R
Veteran / Moderator

May 12, 2014, 10:01 AM

Post #15 of 15 (4132 views)
Re: [goudeuk] removing all lines that contain the asterisk [In reply to] Can't Post

This line will not work correctly if they can't open the files.:

Code
open $FH1, '<', $pwdfile || die "Can't read: '$pwdfile' $!\n";  
open $FH2, '>', $adlist || die "Can't write: '$list' $!\n";


You need to change the || to the lower precedence "or":

Code
open $FH1, '<', $pwdfile or die "Can't read: '$pwdfile' $!\n";  
open $FH2, '>', $adlist or die "Can't write: '$list' $!\n";


Or to add parens:

Code
open ($FH1, '<', $pwdfile) || die "Can't read: '$pwdfile' $!\n";  
open ($FH2, '>', $adlist) || die "Can't write: '$list' $!\n";

to obtain the right precedence.

Otherwise, die will never be called.

The first solution above (with lower precedence "or") is usually the prefered one.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives