Линия #!
не имеет отношения к платформам Windows и только удобство для Unix. Лучше всего, если вы опустите его здесь.
Ваша программа в основном правильная, но позволяет избежать множества удобств, которые Perl обеспечивает, чтобы код был более кратким и понятным.
Вы всегда должны добавить use warnings
в ваш use strict
, так как он подберет простые ошибки, которые вы можете игнорировать.
В открывшемся файле должны использоваться лексические файловые дескрипторы и трехпараметрическая форма open
, и вы должны проверить их успех, поскольку отказ открыть файл делает недействительным большинство последующих кодов. Идиоматических открытым выглядит следующим образом
open my $fh, '<', 'myfile' or die $!;
Он также worh указывая на то, что открытый режим +>>
открывает файл для как читать и Append, который трудно nadle. В этом случае вы имеете в виду только >>
, но лучше всего открыть файл один раз и оставить его открытым на время выполнения программы.
Это переработка вашей программы, которая, я надеюсь, поможет вам. Он использует регулярное выражение, чтобы проверить, отображается ли строка в текущей строке файла. /\Q$string/
идентичен $_ =~ /\Q$string/
, то есть он проверяет переменную $_
по умолчанию. \Q
в регулярном выражении представляет собой quotemeta
, который пропускает любые символы в строке, которые в противном случае могли бы вести себя как специальные символы в регулярном выражении и изменять смысл поиска.Обратите внимание, что в пределах File::Find
wanted
подпрограмма $_
текущая рабочая директория установлена в каталог, в котором сообщается текущий файл. $_
устанавливается в имя файла (без пути), а $File::Find::name
устанавливается в полный файл абсолютной высоты и путь. Поскольку текущий каталог является тем, который содержит файл, легко просто открыть файл $_
, поскольку путь не нужен.
use strict;
use warnings;
use File::Find;
my $dir = 'C:\path\to\dir';
my $string = 'defined';
open my $results, '>', 'results.txt' or die "Unable to open results file: $!";
find (\&printFile, $dir);
sub printFile {
return unless -f and /\.txt$/;
open my $fh, '<', , $_ or do {
warn qq(Unable to open "$File::Find::name" for reading: $!);
return;
};
while ($fh) {
if (/\Q$string/) {
print $results "$File::Find::name\n";
return;
}
}
}
Возможно, вы предпочли бы использовать одну из многих реализаций 'grep' вместо того, чтобы катиться самостоятельно. – bluevector
Как сказано выше, вы можете использовать функцию 'grep()' Perl. Также из опыта я рекомендую вам выводить в STDIN вместо файла (просто 'print()' it). Вы можете перенаправить вывод в файл с помощью '>' redirection. Это позволяет больше гибкости для скрипта (например, переводит вывод на другой процесс и т. Д.). – m0skit0
Я пробовал использовать grep, но он не дал мне результатов, которые я хотел, так как он не показывал мне все содержащиеся подкаталоги. Вот почему я пытаюсь найти другое решение. –