Reputation: 801
Is there any way to guarantee an order from the list returned by readdir
?
I have the code:
opendir(my $DIR, $src) or die "Error opening $src";
# Loop for each file in the directory
while (my $file = readdir($DIR))
{
print "$file\n";
}
But it returns in random order. Now I know there are plenty of solutions via a quick Google search, but I can't find the exact order I need. Basically I want the folders to appear FIRST or LAST, and not in between the files.
For example, right now if I have the folder structure:
folder
folder
file1
file2
file3
I get the result:
file2
folder
folder
file1
file3
When really I want:
folder
folder
file1
file2
file3
Or:
file1
file2
file3
folder
folder
Any way to achieve this?
Upvotes: 9
Views: 10620
Reputation: 471
foreach (sort readdir $dh) {}
works fine for me.
For example:
opendir (my $DIR, "$dir") || die "Error while opening $dir: $!\n";
foreach my $dirFileName(sort readdir $DIR)
{
next if $dirFileName eq '.' or $dirFileName eq '..';
print("fileName: $dirFileName ... \n");
}
Upvotes: 5
Reputation: 50637
You can sort by putting folders first and then sorting by file/dir name,
# $src pointing to folder open with opendir
my @sorted_dir =
map $_->[0],
sort {
$a->[1] <=> $b->[1]
||
$a->[0] cmp $b->[0]
}
map [ $_, -f "$src/$_" ],
readdir($DIR);
While similar effect can be achieved with,
for my $file (sort { -f "$src/$a" <=> -f "$src/$b" } readdir($DIR)) {
print "$file\n";
}
it's slower and inefficient as it more often goes to file system checking if directory entry is a plain file.
Upvotes: 6
Reputation: 20280
You can use part
from List::MoreUtils
#!/usr/bin/env perl
use strict;
use warnings;
use List::MoreUtils 'part';
my $dir = shift || '.';
opendir my $dh, $dir or die "Cannot open $dir";
my ($files, $dirs) = part { -d } sort readdir $dh;
print "$_\n" for @$files, @$dirs;
For another idea, you might look at File::Next.
Upvotes: 2
Reputation: 54323
You could use a sort
to do it, by looking at each entry of the list returned by readdir
.
opendir(my $DIR, '.') or die "Error opening ";
foreach my $file (sort { -d $a <=> -d $b } readdir($DIR)) {
print "$file\n";
}
This will give folders last.
Upvotes: 5