Chci vypsat soubory, pro které existují v daném adresáři VŠECHNY tyto soubory:
<filename>.wed
<filename>.tis
<filename>.are
<filename>LM.bmp
Momentálně to dělám pomocí find
a sed
. Funguje to, ale je to nevkusné a pomalé!
find . -iname "*.wed" -exec echo {} \; | sed s/.wed$// $1 | sed s/..// $1 | while read in; do find . -name "$in.are"; done | sed s/.are$// $1 | sed s/..// $1 | while read in; do find . -name "$in.tis"; done | sed s/.tis$// $1 | sed s/..// $1 | while read in; do find . -name "$in*.bmp"; done
V podstatě řetězím find
, dva sed
a while read
pro každé rozšíření, podle kterého chci filtrovat.
Sotva 30 000 souborů trvá> 35 s! Jak to mohu zlepšit?
Příklad
Pokud jsou v adresáři soubory s názvem AR0505.are
, AR0505.tis
, AR0505.wed
a AR0505LM.bmp
, pak skript vypíše „AR0505“.
Pokud jeden nebo více těchto souborů chybí, skript jej nevytiskne.
Přijatá odpověď:
Myslím, že hlavním úzkým hrdlem je počet procesů, které spustíte. Zde je jednoduchý skript, který vypíše a filtruje váš adresář v jednom průchodu:
#!/usr/bin/perl
use strict;
use warnings;
my %files;
my $dir;
my @extensions = ("\.tis","\.are","LM\.bmp","\.wed");
opendir($dir, ".") || die "Error opening dir\n";
while (my $file = readdir($dir)) {
foreach my $ext (@extensions) {
if ($file =~ /^(.*)$ext$/sm) {
$files{$1} += 1;
}
}
}
closedir($dir);
foreach my $file (keys %files) {
if ($files{$file} == scalar(@extensions)) {
print "$file\n";
}
}