Как я могу перечислить файлы с помощью 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