Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Help to split

by semenych (Initiate)
on Mar 16, 2013 at 04:16 UTC ( #1023808=perlquestion: print w/ replies, xml ) Need Help??
semenych has asked for the wisdom of the Perl Monks concerning the following question:

Hello guys

.

I am very new to Perl. I am trying to do my best, but it's difficult for me. Here is my problem: I have a file in a directory /pub/cs/dputnam/cs113a/passwd. The file itself looks like this:

bsulli03:*:32452:5002:barry sullivan,l230,555-6666,:/students/bsulli03 +:/usr/bin/ksh sbarto22:*:32453:7990:sally bartok,l134,444-3333,:/students/sbarto22:/ +usr/bin/ksh sbarto25:*:32453:7990:sparky bartok,l135,444-4444,:/students/sbarto25: +/usr/bin/ksh sbarto35:*:32453:7990:sammy bartok,l137,444-5555,:/students/sbarto35:/ +usr/bin/ksh sdemar03:*:32454:7990:sally demartra,S23,233-5234,:/students/sdemar03: +/usr/bin/ksh sdemar05:*:32454:7990:bill demartra,l123,555-1234,:/students/sdemar05: +/usr/bin/ksh singl04:*:32455:5002:bart singleton,l134,555-1235,:/students/singl:/us +r/bin/ksh gomez:*:32456:7990:bill gomez,l433,535-6666,:/students/gomez:/usr/bin/ +ksh bolde01:*:32457:7990:bart bolden,l444,444-1234,:/students/bolde:/usr/b +in/ksh reaga09:*:32458:7990:cal reagan,l455,333-1234,:/students/reaga:/usr/bi +n/ksh liu44:*:32460:5002:tom liu,s213,222-1234,:/students/liu:/usr/bin/ksh ulano:*:32462:7990:sally ulanouskay,s233,222-9999,:/students/ulano:/us +r/bin/ksh tran56:*:32463:5002:phuong tran,s111,444-8888,:/students/tran:/usr/bin +/ksh mehr:*:32464:5003:cindy mehr,c113,555-8888,:/students/mehr:/usr/bin/ks +h ramos:*:32449:7990:olivo ramos,l454,999-0000,:/students/ramos:/usr/bin +/ksh brown:*:32459:7990:bart bro,l477,888-7654,:/students/brown:/usr/bin/ks +h mojic:*:32461:7990:celia mojica,c242,555-7654,:/students/mojic:/usr/bi +n/ksh fisher:*:2915:208:cindy fisher,l312,478-0371,:/users/fisher:/usr/bin/k +sh bsulli02:*:32452:5002:bart sullivan,l130,555-5555,:/students/bsulli02: +/usr/bin/ksh

I have to use one or more calls to split() to extract first names from the file. Please help.

I did something:

#!/usr/local/bin/perl open(NAMES,"/pub/cs/dputnam/cs113a/passwd"); @personal=split(":",$_); foreach(@personal){ print"$_\n"; @next=split(",",$_); foreach(@next){ @after=split(" ",$_); print"$_"; } } close NAMES;

but it's not working.

Please, tell me about my mistakes and help me this my work.

Comment on Help to split
Select or Download Code
Re: Help to split
by 2teez (Priest) on Mar 16, 2013 at 05:10 UTC

    Hi semenych,
    "...tell me about my mistakes..."

    • First of all, it good practice to use strict and warnings in your scripts.
    • Using the open function in Perl, you should always check the return, in case it fails. The same should goes for the close function
    "...and help me this my work.."
    After your file was opened, using a "while" loop read your file one at a time. Then use regex, "pick out" the portion of the line you wanted like so:
    use warnings; use strict; while (<DATA>) { chomp; print $1, $/ if /:(\w+?)\s\w+?,/; } __DATA__ bsulli03:*:32452:5002:barry sullivan,l230,555-6666,:/students/bsulli03 +:/usr/bin/ksh sbarto22:*:32453:7990:sally bartok,l134,444-3333,:/students/sbarto22:/ +usr/bin/ksh sbarto25:*:32453:7990:sparky bartok,l135,444-4444,:/students/sbarto25: +/usr/bin/ksh sbarto35:*:32453:7990:sammy bartok,l137,444-5555,:/students/sbarto35:/ +usr/bin/ksh sdemar03:*:32454:7990:sally demartra,S23,233-5234,:/students/sdemar03: +/usr/bin/ksh sdemar05:*:32454:7990:bill demartra,l123,555-1234,:/students/sdemar05: +/usr/bin/ksh singl04:*:32455:5002:bart singleton,l134,555-1235,:/students/singl:/us +r/bin/ksh gomez:*:32456:7990:bill gomez,l433,535-6666,:/students/gomez:/usr/bin/ +ksh bolde01:*:32457:7990:bart bolden,l444,444-1234,:/students/bolde:/usr/b +in/ksh reaga09:*:32458:7990:cal reagan,l455,333-1234,:/students/reaga:/usr/bi +n/ksh liu44:*:32460:5002:tom liu,s213,222-1234,:/students/liu:/usr/bin/ksh ulano:*:32462:7990:sally ulanouskay,s233,222-9999,:/students/ulano:/us +r/bin/ksh tran56:*:32463:5002:phuong tran,s111,444-8888,:/students/tran:/usr/bin +/ksh mehr:*:32464:5003:cindy mehr,c113,555-8888,:/students/mehr:/usr/bin/ks +h ramos:*:32449:7990:olivo ramos,l454,999-0000,:/students/ramos:/usr/bin +/ksh brown:*:32459:7990:bart bro,l477,888-7654,:/students/brown:/usr/bin/ks +h mojic:*:32461:7990:celia mojica,c242,555-7654,:/students/mojic:/usr/bi +n/ksh fisher:*:2915:208:cindy fisher,l312,478-0371,:/users/fisher:/usr/bin/k +sh bsulli02:*:32452:5002:bart sullivan,l130,555-5555,:/students/bsulli02: +/usr/bin/ksh
    Note:Am assuming that the first names are the names that come first in the full names.
    Output:
    barry sally sparky sammy sally bill bart bill bart cal tom sally phuong cindy olivo bart celia cindy bart

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me

      Thanks,2teez

        Or more simply, without going for exact perl. You could use:
        perl -e 'print `cat file|cut -d "," -f1|cut -d ":" -f5|cut -d " " -f1` +;'
        (Replace file with exact name of your file and/or absolute path). Output: barry sally sparky sammy sally bill bart bill bart cal tom sally phuong cindy olivo bart celia cindy bart

      2teez, unfortunately I have not learnt regex yet. Could you please advice how to do it without regexes, maps and other staff, just using one or more split

        "..Could you please advice how to do it without regexes, maps and other staff, just using one or more split.."
        The answer you seek has been given to you in one of the Athanasius's post. Please, check again.

        Hope, this helps

        If you tell me, I'll forget.
        If you show me, I'll remember.
        if you involve me, I'll understand.
        --- Author unknown to me
Re: Help to split
by davido (Archbishop) on Mar 16, 2013 at 05:38 UTC

    I prefer 2teez's solution; it's the way to do it. But you specified that it should be done with one or more calls to split.

    It's usually a better practice when asking for help here to explain what you've tried, and how it's failing, but not to dictate what tools a proper solution should employ. You're likely to get more elegant solutions if you don't limit people such. Nevertheless, if one or more calls to split is the solution you would prefer, you could do something like this:

    use strict; use warnings; use feature qw( say ); # Warning: Big slurp! ;) say for map { ( split /\s/, $_, 2 )[0] } # 3: split on whitespace. map { ( split /:/, $_, 5 )[4] } # 2: split on colons. <DATA>; # 1: auto-split on newlines. __DATA__ bsulli03:*:32452:5002:barry sullivan,l230,555-6666,:/students/bsulli03 +:/usr/bin/ksh sbarto22:*:32453:7990:sally bartok,l134,444-3333,:/students/sbarto22:/ +usr/bin/ksh sbarto25:*:32453:7990:sparky bartok,l135,444-4444,:/students/sbarto25: +/usr/bin/ksh sbarto35:*:32453:7990:sammy bartok,l137,444-5555,:/students/sbarto35:/ +usr/bin/ksh sdemar03:*:32454:7990:sally demartra,S23,233-5234,:/students/sdemar03: +/usr/bin/ksh sdemar05:*:32454:7990:bill demartra,l123,555-1234,:/students/sdemar05: +/usr/bin/ksh singl04:*:32455:5002:bart singleton,l134,555-1235,:/students/singl:/us +r/bin/ksh gomez:*:32456:7990:bill gomez,l433,535-6666,:/students/gomez:/usr/bin/ +ksh bolde01:*:32457:7990:bart bolden,l444,444-1234,:/students/bolde:/usr/b +in/ksh reaga09:*:32458:7990:cal reagan,l455,333-1234,:/students/reaga:/usr/bi +n/ksh liu44:*:32460:5002:tom liu,s213,222-1234,:/students/liu:/usr/bin/ksh ulano:*:32462:7990:sally ulanouskay,s233,222-9999,:/students/ulano:/us +r/bin/ksh tran56:*:32463:5002:phuong tran,s111,444-8888,:/students/tran:/usr/bin +/ksh mehr:*:32464:5003:cindy mehr,c113,555-8888,:/students/mehr:/usr/bin/ks +h ramos:*:32449:7990:olivo ramos,l454,999-0000,:/students/ramos:/usr/bin +/ksh brown:*:32459:7990:bart bro,l477,888-7654,:/students/brown:/usr/bin/ks +h mojic:*:32461:7990:celia mojica,c242,555-7654,:/students/mojic:/usr/bi +n/ksh fisher:*:2915:208:cindy fisher,l312,478-0371,:/users/fisher:/usr/bin/k +sh bsulli02:*:32452:5002:bart sullivan,l130,555-5555,:/students/bsulli02: +/usr/bin/ksh

    Dave

      Or you can dispense with map by chaining the calls to split:

      #! perl use strict; use warnings; print +(split / /, (split /,/, (split /:/)[4])[0])[0], "\n" while <DAT +A>;

      Or as a one-liner:

      16:05 >perl -pwe "$_ = (split / /, (split /,/, (split /:/)[4])[0])[0] +. qq[\n];" passwd barry sally sparky sammy sally bill bart bill bart cal tom sally phuong cindy olivo bart celia cindy bart 16:05 >

      :-)

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Thanks Athanasius

      Thanks, Dave. But unfortunately I have not learnt map yet. Could you please advice to do it the easiest way, probably, just using one or more split calls. Thanks again

      Thanks Dave for your advice. But unfortunately I have not learnt map yet. As I understand I am supposed to do it with while or for loops and using one or more split calls. Could you please help to write it in the easiest way. Thanks again

      It's usually a better practice when asking for help here to explain what you've tried, and how it's failing, but not to dictate what tools a proper solution should employ.
      He may not have explicitly stated it, but this is clearly a homework assignment. The "solve by using split one or more times" requirement is part of the assignment. Even if he knew other ways to do it, the instructor has declared them to be out of bounds.

      Beyond that, he's also provided his source code in the question, which qualifies as "explain[ing] what you've tried" in my book. The only thing missing from the question is a statement of how it fails, although I expect that was obvious to most experienced monks pretty quickly (as CountZero said, he forgot to read from the file after opening it).

      Pliiiiz, don't use regexps in your split. They are scary and OP doesn't want to be scared :)

        Pliiiiz, don't use regexps in your split. They are scary and OP doesn't want to be scared :)
        by grizzley

        Eeeep! A talking grizzley!

Re: Help to split
by CountZero (Bishop) on Mar 16, 2013 at 08:02 UTC
    Of course it is not working.

    You open the file but you never read from it.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: Help to split
by j0se (Pilgrim) on Mar 16, 2013 at 10:22 UTC

    Hello, another way (more suitable for a beginner?) to do it:

    #!/usr/bin/perl use strict; use warnings; # Get the filename as command line argument my $filename = shift; open my $fh, "<", $filename or die "Can't open $filename"; while ( my $line = <$fh> ) { # go through file, line by line my @fields = split ':', $line; my ($first) = split /\s+/, $fields[4]; print "$first\n"; } close $fh;

    Excellence is an art won by training and habituation: we do not act rightly because we have virtue or excellence, but we rather have these because we have acted rightly. -- Will Durant

Re: Help to split
by Mr. Muskrat (Abbot) on Mar 16, 2013 at 15:51 UTC

    Personally, I'd just use Passwd::Unix but since this is homework you probably don't have that luxury.

      Agreed. The question feels homework-ish on its own, but the directory /pub/cs/dputnam/cs113a/passwd is hard to explain in any other context.

      Christopher Cashell

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1023808]
Approved by Athanasius
Front-paged by 2teez
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2014-09-18 05:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (108 votes), past polls