Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

How to efficiently parse "ls -a"?

by isync (Hermit)
on Dec 15, 2011 at 19:42 UTC ( [id://943820]=perlquestion: print w/replies, xml ) Need Help??

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

Monks,
what's an efficient way of parsing a directory listing produced by ls -a?

File::Listing seems to rely on newlines, and using ls -al to obtain item-names only would mean parsing a lot of unneeded data, that's why...

Replies are listed 'Best First'.
Re: How to efficiently parse "ls -a"?
by jettero (Monsignor) on Dec 15, 2011 at 20:14 UTC
    The most efficient way to parse ls -a is to use stat (and lstat) instead.
Re: How to efficiently parse "ls -a"?
by Your Mother (Archbishop) on Dec 15, 2011 at 21:14 UTC

    Something a bit more high level than readdir and stat to play with, Path::Class

    perl -MPath::Class=dir -le 'print join $/, sort(dir(".")->children)'
Re: How to efficiently parse "ls -a"?
by moritz (Cardinal) on Dec 16, 2011 at 04:30 UTC

    On GNU systems you can use ls -Q, which puts double quotes around file names, and escapes newlines as \n and quotes as \". Or the -b option, which does just the escaping without quoting. That output can be parsed unambiguously.

Re: How to efficiently parse "ls -a"?
by Khen1950fx (Canon) on Dec 15, 2011 at 23:41 UTC
    Would this be any better?
    #!/usr/bin/perl use strict; use warnings; use File::Listing qw(parse_dir); use IPC::System::Simple qw(capture); my(@dirs) = '/root'; my $cmd = capture("ls -a"); @dirs = map( { my ( $name, $type, $size, $mtime ) = @$_; $type eq 'd' ? $name : () } parse_dir($cmd) ); print $cmd;
Re: How to efficiently parse "ls -a"?
by jdrago999 (Pilgrim) on Dec 15, 2011 at 21:36 UTC

    What's wrong with the glob operator thing?

    my $dir = '/the/path/here'; my @files = <$dir/*>;
Re: How to efficiently parse "ls -a"?
by TJPride (Pilgrim) on Dec 15, 2011 at 20:07 UTC
    Are you in a situation where you can't opendir and readdir?

    When I run the ls -a command from my Perl script, I get it all in one column automatically. Assuming your list is in the column format somehow, however:
    @files = sort split /  +|\n/, $lsdata;

      I admit, my initial post was a little short.

      Well, yes, I am in a situation where I actually *have to* avoid perl filesystem methods. I'm working on an improved Filesys::Virtual::SSH, as the original doesn't reuse the ssh connection, for example.

      The approach is similar to what IPC::PerlSSH does, except that I even have to drop the remote perl from the mix. So this here sshs into remote, and then executes system binaries, reading their output, then parsing this on the local end.
      I would try to avoid executing perl on the other end wherever possible.

      That's why I'd like to parse the brief "ls -a", in a way that allows all sorts of chars in the filenames.

      The more I think about it. I might run into a situation where I can't avoid calling perl on the remote end. But really: why should I?? Continuing to use Net::SSH::Expect and solving the parsing of binaries could become a reinvention of the wheel... And perl is also just another binary readily available on most systems. I think I should switch over to IPC::PerlSSH for the hard work. RFC, guys.
Re: How to efficiently parse "ls -a"?
by thargas (Deacon) on Dec 16, 2011 at 14:19 UTC
    How about ls -a1 That's the lowercase of the letter A followed by the digit one. It'll get you the list of file-names one per line. Unless you're concerned about silly file-names including newlines.

Log In?
Username:
Password:

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

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

    No recent polls found