2015-04-01 3 views
0

У меня есть каталог $tmp, который содержит файлы с синтаксисом имен .X*-lock, а также другие простые файлы и каталоги.Perl: opendir, while readdir, next if, hash

Я сравниваю содержимое $tmp со значениями в хеш-таблице, соответствующей .X*-lock именам файлов, которые НЕ следует удалять. Затем я хочу, чтобы скрипт удалял все, и ТОЛЬКО .X*-lock файлов, которые не находятся в хеш-таблице. Он не может удалить обычные файлы (не файлы «»), каталоги, или . & ..

Вот код:

my %h = map { $_ => 1 } @locked_ports; 
#open /tmp and find the .X*-lock files that DO NOT match locked_ports (NOT WORKING) 

opendir (DIR, $tmp) or die "Error in opening dir $tmp\n"; 
    while ((my $files = readdir(DIR))) 
    { 
     next if((-f $files) and (-d $files)); 
     next if exists $h{$files}; 
     #unlink($files) if !-d $files; 
     if (! -d $files){print "$files\n"}; 
    } 
     closedir(DIR); 

Как вы можете видеть, потому что теперь я заменил unlink с print так что я знаю перечислены соответствующие файлы.

Скажем, в моем $tmp директории у меня есть следующие файлы и каталоги:

./ 
../ 
cheese 
.X0-lock 
.X10-lock 
.X11-unix/ 
.X1-lock 
.X2-lock 
.X3-lock 
.X4-lock 
.X5-lock 

Но только .X1-lock в хэш-таблице. Таким образом, я хочу, чтобы напечатать/удалить все другие .X*-lock файлы, но не .X11-unix/ Дира файл cheese, или . & ..

С выше код, он не печатает . или .., которая хороша, но она делает печать cheese и .X11-unix. Как я могу изменить его, чтобы они не были напечатаны?

(примечание:. Это стебель от Perl: foreach line, split, modify the string, set to array. Opendir, next if files=modified string. Unlink files мне сказали, чтобы прекратить задавать больше вопросов в комментариях, так что я сделал новый вопрос)

Спасибо!

+1

Я не думаю, что это проблема, которую вы описываете, но имейте в виду, что 'readdir' не возвращает путь к файлу, просто имя файла. Если вы не являетесь текущим каталогом в '$ tmp', вам нужно заранее указать путь (' $ tmp' здесь), например 'next if -d '$ tmp/$ files" ' –

+0

@JimDavis Изменение строки' next if ((- f $ files) и (-d $ files)); 'to' next if (-d "$ tmp/$ files"); 'избавился от' .X11-unix/'в выходе. Теперь мне просто нужно, чтобы он игнорировал все файлы, кроме тех, у которых синтаксис имени '.X * -lock', поскольку' cheese' все еще появляется. Ближе! Спасибо :) – marcopolo1166

ответ

1

я бы, вероятно, сделать что-то вроде этого:

opendir (my $dirhandle, $tmp) or die "Error in opening dir $tmp: $!"; 
while (my $file = readdir($dirhandle)) { 
    # skip directories and files in our hash 
    next if -d "$tmp/$file" || $h{$file}; 
    # skip files that don't look like .X###-lock 
    next unless $file =~/
     \A # beginning of string 
     \. # a literal '.' 
     X  # a literal 'X' 
     \d+ # 1 or more numeric digits 
     -lock # literal string '-lock' 
     \z # the end of the string 
    /x; # 'x' allows free whitespace and comments in regex 
# unlink("$tmp/$file"); 
    print "$file\n" 
} 
closedir($dirhandle); 

Если вы нашли его более удобным для чтения, что последний условно можно записать в виде:

next if $file !~ /\A\.X\d+-lock\z/; 

или даже:

if ($file =~ /\A\.X\d+-lock\z/) { 
    # unlink("$tmp/$file"); 
     print "$file\n" 
    } 
+0

Это работает! У вас есть где-нибудь, что вы могли бы указать мне, чтобы понять '/ \ A \ .X \ d + -lock \ z /;' немного лучше? Спасибо – marcopolo1166

+0

Есть ['perldoc perlre'] (http://perldoc.perl.org/perlre.html), но я отредактирую ответ, чтобы документировать его немного лучше. –

Смежные вопросы