Как я могу перечислить файлы с помощью find и Perl?

Я работаю на машине на базе HP-UX, и мне нужно перечислить имена журналов, содержащихся в папке, по дате и разделенных именем ";" и результат, отсортированный по дате в порядке убывания, сохраняется в текстовом формате, поэтому содержимое текстового файла будет таким:

2019-02-02;/home/user/Documents/imthelog03.log
2019-02-01;/home/user/Documents/imthelog02.log
2019-01-29;/home/user/Documents/imthelog01.log

Я пробовал это:

find /home/user/Documents/*.log* exec perl -MPOSIX -e 'print POSIX::strftime "%Y%m%d\n", localtime((stat $ARGV[0])[9])'

но я не могу получить то, что мне нужно, я не могу использовать statsЯ использую for читать построчно, так как я могу получить дату и path/filename разделены ; в TXT, отсортированный по дате по убыванию с помощью Bash и в конечном итоге Perl, спасибо!

2 ответа

Решение

Можно сделать все это в Perl

perl -MPOSIX=strftime -wE'$d = shift || "."; 
    say strftime("%Y-%m-%d", localtime((stat $_)[9])), "; $_" 
        for sort { (stat $b)[9] <=> (stat $a)[9] } glob "$d/*log*"
' dir-name

где вы отправляете dir-name в одну строку (или он работает с ., текущий каталог).

Обратите внимание, я не вижу необходимости в find как вы получаете список (журналов) файлов из каталога.

Это можно оптимизировать, чтобы не запускать stat неоднократно, но я сомневаюсь, что это имеет значение в ожидаемом использовании. Я бы порекомендовал поместить это в хороший маленький скрипт, хотя.


Еще, stat не дешево, и если это регулярно ловит длинные списки файлов, используйте

perl -MPOSIX=strftime -wE'$d = shift || "."; 
    say strftime("%Y-%m-%d", localtime($_->[1])), "; $_->[0]" 
        for 
            sort { $b->[1] <=> $a->[1] } 
                map { [$_, (stat $_)[9]] } glob "$d/*log*"
' dir-name

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

Список входных файлов из glob используется для первого построения другого списка, используя map, с arrayref для каждого имени файла: само имя и временная метка этого файла. Тогда парные сравнения в sort не нужно бежать stat каждый раз до конца; они используют временные метки, предварительно рассчитанные один раз. Это называется преобразованием Шварца. Кроме того, sprintf не нужно бежать stat опять же.

Обратите внимание, что оптимизация сопряжена с дополнительными затратами, поэтому используйте ее только тогда, когда она действительно требуется. Смотрите, например, этот пост (последний раздел) для обсуждения и ссылок.

find /home/user/Documents/*.log* -type f -exec perl -MPOSIX -le 'print strftime("%Y%m%d",localtime((stat $ARGV[0])[9])),";$ARGV[0]"' {} \; | sort -k1,1
Другие вопросы по тегам