Найти файлы, созданные после определенного времени в csh на SunOS

Найти файлы, созданные после определенного времени в csh на SunOS

В моей системе SunOS я пытаюсь найти все файлы, созданные после 19:00, используя csh, lsи awk.

ls -l  "${Source_files_Dir}"/*.zip| awk -v today="$(date "+%b %d")" '{
date=$6" "$7; time=$8; if (date == today && substr(time,1,2) >= 19)
print $9 }'|xargs -n 1 basename

Эта команда работает в , kshно не в csh. Как мне добиться этого в csh?

Примечание: -newermtопция не поддерживается в findSunOS, поэтому я попробовал использовать указанную выше lsкоманду.

решение1

В любом случае этот подход довольно ненадежен, лучше использовать perl:

perl -MPOSIX -MFile::Basename -le '@start = localtime; @start[0..2] = (0,0,19); $start = mktime(@start); for (@ARGV) {print basename$_ if @s = stat$_ and $s[9] >= $start}' -- "$Source_files_Dir"/*.zip

Не уверен, зачем вам использовать csh в этом столетии, но обратите внимание, что вышеприведенное не работает должным образом, cshесли $Source_files_Dirсодержит символы новой строки. Замена "$Source_files"на $Source_files:qбыла бы лучше в csh (но больше не работает в других оболочках).

Solaris (ранее известная как SunOS) также обычно устанавливается zsh, и для этого достаточно сделать следующее:

autoload age
print -rC1 -- $Source_files_Dir/*.zip(Ne[age 19:00]:t)

Перечислим некоторые проблемы вашего подхода:

  • ls -l "${Source_files_Dir}"/*.zip: если $Source_files_Dirначинается с -, то он будет рассматриваться как опция ls. Как правило, вам необходимо --отметить конец опций, если то, что следует за ними, является переменной.
  • если какой-либо из zip-файлов имеет тип каталога, то будет перечислено его содержимое. При использовании lsс glob или вообще переменными данными, вы обычно хотите использовать опцию -d:ls -ld -- ...
  • В частности, в csh, если $Source_files_Dirон содержит символы новой строки, это вызовет синтаксическую ошибку. $Source_files_Dir:qЛучше в csh, как отмечено выше.
  • В любом случае вы предполагаете, что пути к файлам (имена файлов и цели символических ссылок, которые ls -lтакже сообщаются) не содержат символов новой строки, поскольку вы обрабатываете вывод на lsоснове строк.
  • Вы предполагаете, что дата/время находятся в полях 6, 7, 8, которые развалятся, если имена пользователей или групп содержат пробелы. Использование -nвместо (или в дополнение к) -lдля получения числовых uid/gids сделает его более надежным (и позволит избежать потенциально дорогостоящего перевода в имена).
  • date +%dвыводит число, дополненное нулями, тогда как во многих lsреализациях и во многих локалях (а это требование POSIX в локали C/POSIX) ls -lвыводит число, дополненное пробелами ( date +%e).
  • ls -lвыводит данные Mon dd HH:MMне для последних дат, а Mon dd YYYYдля других дат, которые ваш подход не обрабатывает.
  • без этой -Lопции для символических ссылок будет указано время модификации символической ссылки, а не время модификации zip-файла, на который она указывает. perl's stat()или zsh' ageработают с mtime цели.
  • с вашим {print $9}, в дополнение к именам пользователей/групп, не содержащим пробелов, вы предполагаете, что пути к файлам также не содержат пробелов.
  • использование xargsэтого необработанного вывода завершится ошибкой, если пути к файлам содержат обратные косые черты или кавычки, а также если не запустить его в локали C, то для имен файлов, которые не являются текстом, закодированным в кодировке локали.
  • Если в каталоге нет нескрытого zip-файла, в csh вы получите ошибку No matchи lsне запустите его (что, по крайней мере, лучше, чем поведение в стиле Bourne, когда lsвызывается буквально с шаблоном), но он xargsвсе равно будет запущен, и basenameвсе равно будет запущен один раз без аргумента, что, вероятно, вызовет запутанную ошибку.

решение2

Я получил ответ для csh, вместо того '$'чтобы backticksсохранить сегодняшнюю дату в переменной, todayа не получить ее в awk.

set today=`date "+%b %d"`
ls -l "$Source_files_Dir"/*.zip | awk -v today="$today" ' \
{ \
    date=$6" "$7; \
    time=$8; \
    if (date == today && substr(time,1,2) >= 19) print $9; \
}'|xargs -n 1 basename

Связанный контент