I'm, every now and then, missing a "tree" command at places where I have to work.
And every now and then I "reinvent the wheel".
To put an end to this, I decided to present my current version here.
I hope it's useful to others and maybe I'll get some constructive feedback?
Update: Added AppleFritter's suggestion of hiding hidden files
#!/bin/env perl
use strict;
use warnings;
use Getopt::Long qw(:config no_ignore_case);
use Pod::Usage;
my (
$showall, # show hidden files
$showfiles, # show also files
$showlinks, # show also a symlink's target
);
help() unless GetOptions(
a => \$showall,
l => \$showlinks,
f => \$showfiles,
'h|help' => \&help,
'm|man' => \&man,
);
sub help { pod2usage(-verbose=>1); }
sub man { pod2usage(-verbose=>2); }
my $indent = ' ';
my $indir = '--';
foreach my $path (@ARGV ? @ARGV : '.') {
print $path,"\n";
traverse($path, '');
}
sub traverse {
my ($path, $depth) = @_;
# Open the directory
opendir my $dh, $path or die "Couldn't read $path: $!\n";
# Get all directory content - leaving out files unless asked for
my(@content) = grep {
not /^\.\.?$/
and
( $showfiles or not -f "$path/$_" )
and
( $showall or /^[^.]/ )
} readdir $dh;
closedir $dh;
# How many eitems are in the directory?
my $count= scalar @content;
# Prepare the standard indent
my $i= $depth . '|' . $indent;
# Print all the elements
foreach my $sub (@content) {
my $p= "$path/$sub";
# Prepare the last indent
$i= $depth . ' ' . $indent unless --$count;
print $depth, ($count ? '|' : '\\'), $indir , $sub;
# Is it a link?
if ( -l $p ) {
# Shall they be shown as such
if ($showlinks) {
print " -> ", readlink $p;
}
print "\n";
next;
}
print "\n";
# Done unless it's a directory
next unless -d $p;
traverse($p, $i);
}
return;
}
=head1 NAME
tree - A script to show a "graphical" representation of a directory st
+ructure
=head1 SYNOPSIS
tree [options] [path...]
=head1 DESCRIPTION
tree will show a "graphical" representation of a directory structure,
+including
all files (when B<-f> specified) and link targets (when B<-l> specifie
+d).
=head1 OPTIONS
=over 4
=item B<-f>
Show also files.
=item B<-l>
Shhow also link targets.
=item B<-h>
=item B<--help>
show a short help page.
=item B<-m>
=item B<--man>
Show the man-page.
=back
=head1 AUTHOR
Skeeve of perlmonks.org (perlmonks DOT org DOT Skeeve at XoXy dot net)
Including ideas of Apple Fritter, a fellow Perl monk
=cut
s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
+.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.