2016-05-30 4 views
2

Я переписываю скрипт Bash в Perl, чтобы узнать последний.Как проверить наличие имен файлов с определенной строкой в ​​Perl

Сценарий создает файл с использованием текущей даты в пользовательском формате и расширение «.txt», но сначала проверяет, чтобы файл с указанной датой уже не существовал.

В Баше я выполняю это с ls |grep $customDate как условие. То есть, если ls |grep $customDate правда, выдается предупреждение и файл не создавать, а если ls |grep $customDate ложно, то файл будет создан с пользовательской датой плюс «.txt»

Как я могу имитировать это в Perl?

Для целей тестирования, я написал код, приведенный ниже, но не печатать ничего - даже тогда, когда я создал файл, который удовлетворяет условию:

use POSIX qw(strftime); 

$customDate = strftime "%Y_%m%b_%d%a", localtime; 

opendir(DIR, ".") or die "$!"; 
my @FILES = grep { /${customDate}*/ } readdir(DIR); 
closedir(DIR); 

print "$_\n" for @FILES; 

Я прошу прощения, если мой вопрос не ясно

+1

, похоже, работает нормально. – SilentMonk

+1

Если в текущем каталоге есть файл с именем, который содержит '2016_05May_30Mo', код, который вы отправили, будет печатать свое имя по своему желанию. – ikegami

+0

любая идея, почему это сработает для вас двоих, а не для меня? – cannonfodder

ответ

-1

Причина, по которой вы не получаете то, что вы ожидаете, - это * в grep, ища последний символ «$ customDate», повторяемый столько раз, сколько ему нравится (это не то, что вы ожидаете от * в этом случае) ,

Если файл имеет «somedata.txt» вн, вы должны обновить код как таковой, который будет искать для строки даты, то любое число символов, за которым следует ТХТ:

$customDate = strftime "%Y_%m%b_%d%a", localtime; 

opendir(DIR, ".") or die "$!"; 
my @FILES = grep { /${customDate}.*\.txt/ } readdir(DIR); 
closedir(DIR); 

print "$_\n" for @FILES; 
+0

1) Разве вы не имеете в виду '/ \ Q $ {customDate} \ E \ .txt \ z /' или '/^\ Q $ {customDate} \ E \ .txt \ z /'? 2) Я не вижу, как это вообще затрагивает проблему. ОП жалуется, что у него недостаточно совпадений, и то, что вы указали, ограничивает то, что соответствует. – ikegami

+0

@ Wayne Booth: имена файлов содержат пользовательский формат даты и заканчиваются на «.txt», но могут также содержать текст между датой в расширении: '2016_05may_22.txt' или' 2016_05may_30mon__payroll.txt'. Я попробовал то, что вы предлагаете, и он тоже не работает. – cannonfodder

+1

@cannonfodder \t Я пропустил это требование в вашем вопросе.Если вам нужно что-то после отметки времени, нам нужно другое выражение grep. Обновляя свой ответ в соответствии с номером –

0

«Я переписываю скрипт Bash в Perl, чтобы узнать последнее».

Я думаю, что вы используете неправильный подход к изучению Perl или изучению любого языка.

Несмотря на то, что между процедурными языками всегда много общего, всегда неправильно фокусироваться на тех, которые выше различий. Языки программирования должны изучаться с нуля, если вы надеетесь когда-либо читать и писать их хорошо.

Я регулярно вижу код Perl в переполнении стека, который явно написан кем-то с неправильной головкой. Например, отчетливые признаки C программиста являются

  • Декларирование все в одном блоке в верхней части исходного файла

  • Чрезмерная использования scalar и круглые скобки

  • Под -использование переменной по умолчанию$_ и регулярные выражения

  • Используя цикл C-стиль for, который обычно выглядит примерно так в Perl

    my $i; 
    
    for ($i=0; $i<=scalar(@data); $i++) 
    { 
        process($data[$i]) 
    } 
    

    Помимо игнорирования perlstyle полностью, автор хватается за что-то знакомое, вместо того, чтобы охватить новый язык.В идиоматических Perl, который должен выглядеть

    process($_) for @data 
    

Достигнув дальше, легко почивать на лаврах о последствиях фраз вы можете писать многословно в оболочке

Вы должны знать, что ваш заявление оболочки

ls |grep $customDate 

начинает новые процессы для запуска /bin/ls и /bin/grep, и обжигающе информацией между ними и обратно в с адский процесс. Linux оболочка и ее вспомогательные утилиты предназначены, чтобы получить тривиальные работы легко сделать, но я считаю, что они используют слишком много со сложным сценарием оболочки однострочечников, которые являются непрозрачными и за отладку



это очень трудно точно сказать, что это то, что вам нужна ваша программа, чтобы сделать, но это выглядит, как вы хотите узнать, есть ли какие-либо файлы, которые содержат строку как 2016_05May_30Mon в текущем каталоге

Я должен сказать, это ужасный формат даты и времени, и я изо всех сил верить, что это то, что вы хотите, но я бы предпочел основной Time::Piece модуль Perl над POSIX в любое время

В этом случае я бы также использовать О.Д. регулярных выражений Perl, тем -X * файловые испытательные операторы и оператор glob Perl вместо opendir, readdir, closedir. Ни один из них не имеет прямой эквивалент в любом языке оболочки

Таким образом, если предположить, что мои догадки о своем намерении правильно, я бы написал этот

use strict; 
use warnings 'all'; 
use feature 'say'; 

use Time::Piece; 

my $dtime = localtime()->strftime('%Y_%m%b_%d%a'); 

say for grep { -f and /$dtime/ } glob '*.txt'; 

который не отдаленно, как ваш перевод с оболочки на Perl

+0

, ваш ответ иллюстрирует, почему я ненавижу обращение к форумам за помощью ... его педантичный тон является корыстным, но в конечном счете, мало пользы для оригинального плаката, спасибо вам большое ... кстати, пока вы вроде сорта понять, что это мой первый удар в perl, должен делать (после того, как он слишком сильно сосредоточился на зле, желая написать скрипт perl, который делает то же самое, что у меня уже есть скрипт bash), ваш ответ не работает. или его уровень выше моего уровня ... в любом случае, жизнь слишком коротка, чтобы тратить больше времени на это ... – cannonfodder

+1

@cannonfodder: Мне жаль, что вы так себя чувствуете. Ваше предложение * «Я переписываю скрипт Bash в Perl, чтобы узнать последний». * Стоит один на первое место в вашем сообщении. Я предположил, что это был основной путь вашего вопроса, поэтому я обратился к этому с учетом этого. Я согласен с тем, что переписывание программ с другого языка - плохой способ освоить новый язык. Хотя я думаю, что вы можете изучить * lot *, написав простые утилиты командной строки, такие как 'ls' и' grep 'без ссылки на оригинал C. И мой код отлично работает для меня: вам нужно запустить его как' perl program.pl' – Borodin

+0

@cannonfodder. Я думаю, может быть, вы слишком негативны в своем первом комментарии. По-моему, этот ответ достаточно хорошо написанный и может стать источником полезной информации для пользователей этого форума в будущем (обратите внимание, что ответы написаны для широкой аудитории, поэтому нет необходимости брать что-либо личное). –

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