Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Problem stripping directory listing

by Anonymous Monk
on Feb 15, 2003 at 07:22 UTC ( [id://235512]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,
The script is used to list the usernames in the "users" folder. The problem i am facing is that i am getting multiple entries if the username folder contains more than one folder. How can i solve this problem?

Folder Structure like this:

/home/sites/$arg1/users/XY/ /home/sites/$arg1/users/YZ/bbb/ /home/sites/$arg1/users/BD/ss/ /home/sites/$arg1/users/GD/gg/ /home/sites/$arg1/users/ZX/
Using my code i am getting result stored as
XY YZ YZ BD BD GD GD ZX
But i need to get a result as:
XY YZ BD GD ZX #!/usr/bin/perl $arg1 = $ARGV[0]; @filelist = ` find /home/sites/$arg1/users -type d `; chomp @filelist; @store = (); foreach $fle(@filelist) { ($junk, $reqd )=split (/\/users\//,$fle); ($reqd, $junk) = split (/\//,$reqd); push (@store,$reqd); }
So pls help me to solve this problem.

edited: Sun Feb 16 17:27:11 2003 by jeffa - title change(was: pls modify this code)

Replies are listed 'Best First'.
Re: Problem stripping directory listing
by tachyon (Chancellor) on Feb 15, 2003 at 10:24 UTC

    Here are a couple of ways to do it. With perl you dont need to shell out very much as most of the standard shell utilities are available in pure Perl. opendir readdir grep map and glob are all handy

    #/usr/bin/perl opendir DIR, "$ARGV[0]/users" or die $!; @dirs = grep { -d "$ARGV[0]/users/$_" and not /^\./ }readdir DIR; print "$_\n" for @dirs; #/usr/bin/perl @fullpath = grep { -d and not /^\./ } glob "$ARGV[0]/users/*"; @dirs = map { s!\Q$ARVG[0]\E/users/!!; $_ } @fullpath print "$_\n" for @dirs;

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Problem stripping directory listing
by integral (Hermit) on Feb 15, 2003 at 08:43 UTC
    Couple of points from me: You can replace the use of `find` with the File::Find module which uses perl, although this would require restructuring your code, because of the callback style interface of that module.

    The second point is that your use of split could be optimised. This is one situation where a regex with capturing parenthesis could be used instead (see perlop for more about the return value of m// in list context).

    my ($reqd) = m{users/(.+?)/};

    --
    integral, resident of freenode's #perl
    
Re: Problem stripping directory listing
by zengargoyle (Deacon) on Feb 15, 2003 at 08:50 UTC

    try `find /home/sites/$arg1/users -type d -maxdepth 1`.

    this might be the more perlish way...

    my $which_site = shift @ARGV or die "Usage: $0 <sitename>\n"; my $home = "/home/sites/$which_site/users"; use Cwd; my $old_cwd = cwd(); # keep current working directory chdir $home or die "Can't chdir: $!\n"; opendir(HOME, '.') or die "Can't opendir: $!\n"; my @users = grep { !/^\./ # skip any .file_or_dir esp . and .. and -d # is it a directory? } readdir(HOME); closedir(HOME); # go back to where we started chdir $old_cwd or die "Can't chdir: $!\n"; print join "\n", @users, '';
      zengargoyle++ for that. But I don't see why it's necessary to chdir to the directory just to read it. Also, IO::Dir makes things somewhat easier.
      use IO::Dir; my @users = (IO::Dir->new($home) or die "$home: $!")->read; print join "\n", @users, '';
      Update: thanks to zengargoyle's note below. Ooops!
      my @users = grep { !/^\./ and -d "$home/$_" } (IO::Dir->new($home) or die "$home: $!")->read;

      jdporter
      The 6th Rule of Perl Club is -- There is no Rule #6.

        chdir was so i didn't have to do -d "$home/$_" for everything.. your solution would likely include . and .. and any files that happened to be loitering around. not that this is likely the best way to find a list of users anyways =P

Re: Problem stripping directory listing
by dws (Chancellor) on Feb 15, 2003 at 07:33 UTC
    The problem i am facing is that i am getting multiple entries if the username folder contains more than one folder. How can i solve this problem?

    If you're getting more entries than you expect, then there are more entries in @filelist than you expect. Adding

    print "$fle\n";
    at the top of your loop might tell you why.

Re: Problem stripping directory listing
by steves (Curate) on Feb 15, 2003 at 09:06 UTC

    All the other Perl changes suggested are good ones but the core of your problem is the find change suggested by zengargoyle. Without a -depth argument to limit the find you're actually getting more directories than you assumed. You're actually probably seeing the following (all directories):

    /home/sites/$arg1/users/XY/ /home/sites/$arg1/users/YZ/ /home/sites/$arg1/users/YZ/bbb/ /home/sites/$arg1/users/BD/ /home/sites/$arg1/users/BD/ss/ /home/sites/$arg1/users/GD/ /home/sites/$arg1/users/GD/gg/ /home/sites/$arg1/users/ZX/

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://235512]
Approved by dws
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2024-04-25 17:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found