Существует две вещи, связанные с выполнением этого:
Первое, которое можно решить при наличии почты быть отправленными на сервер непосредственно, но если сервер не онлайн все время (расположен дома), вероятно, лучше отправить электронные письма в некоторый Google, или Yahoo считают и выбирают их оттуда. Можно сделать это с fetchmail, и поставлять почту локально пользователю list
.
Для второй части можно использовать procmail с определенными правилами для пользователя в ~/.procmailrc
. Курьеру местной почты нужно сказать использовать procmail
например, в postfix
Вы добавляете:
mailbox_command = procmail -a "$EXTENSION"
к Вашему /etc/postfix/main.cf
файл.
В файле ~list/.procmailrc
можно указать правила о том, что сделать с почтой (все письма, прибывающие там или те с определенными характеристиками (предмет, от адреса, и т.д.)). procmail
имеет несколько полезных сборок в действиях, и если они не удовлетворяют, что можно передать почту по каналу в программу, чтобы сделать что-то определенное, которое это не может сделать.
С ksh93
:
$ LC_ALL=C ksh93 -c 'printf "%(%c)T\n" "30-Aug-2015 Saturday"'
Sat Sep 5 00:00:00 2015
Обратите внимание, что если дата - суббота, то она вернется в тот же день, если вы хотите в следующую субботу сделайте это:
LC_ALL=C printf "%(%c)T\n" "30-Aug-2015 tomorrow Saturday"
Замените % c
на требуемую спецификацию strftime
:
$ LC_ALL=C printf "%(%d-%b-%Y)T\n" "03-Jan-2015 tomorrow saturday"
10-Jan-2015
На GNU date
:
$ d=03-JAN-2015
$ LC_ALL=C date -d "$d +1 week -$(date -d "$d +1 day" +%w) day" '+%d-%^b-%Y'
10-JAN-2015
Из того, что вы пробовали, я предполагаю, что вам нужна единственная команда. Мне не удалось его найти, но я адаптировал этот ответ , чтобы делать то, что вы хотите:
# Assume that date1 is already set to "30-AUG-2015"
try_date="$date1"
while [ "$(date --date="$try_date" +"%A")" != Saturday ]
do
try_date=$(date --date="$try_date + 1 day" +"%d-%b-%Y")
done
date2="$try_date"
echo "$date2"
Вывод:
05-Sep-2015
Вы можете изменить строку , а
на либо
while ["$ (date --date =" $ try_date "+"% a ")"! = Sat]
while ["$ (date --date =" $ try_date " + «% 5») «! = 6]
1
для понедельника… 7
для воскресенья) Если $ date1
равно« 29 августа 2015 года »(суббота),
тогда $ date2
будет« 29 августа 2015 года »(то есть в тот же день).
Если вы все же хотите получить 5 сентября 2015 г. для этого ввода
(т. Е. В следующую субботу после $ date1
), измените первую строку {{ 1}} по try_date = $ (date --date = "$ date1 + 1 day" + "% d-% b-% Y")
.
Если вы действительно хотите, чтобы месяц был написан заглавными буквами (например, «SEP»), используйте tr
.
Я настоятельно рекомендую dateutils для подобных вещей. ( yum install dateutils
в Fedora 21+ или CentOS / RHEL 7 с EPEL.) Затем просто выполните:
dateround today sunday
Вы можете использовать «сегодня» или заменить фактическую дату:
$ dateround 2015-08-30 saturday
2015-09-05
Если вам нужно дата ввода должна быть в определенном формате, например 30-AUG-2015, вы можете использовать -i
или - input-format
, например:
$ dateround -i '%d-%b-%Y'30-AUG-2015 saturday
2015-09-05
Мой лучший ответ на этот вопрос:
IFS="#"; ((
for s_date in $(echo ${date1}' +'{1..7}' days#'); do
date -d "${s_date}";
done
) | grep Sat
) | xargs -I {} date +%d-%b-%Y -d "{}"
Выход:
05-Sep-2015
Это создает список из #
разделенных строк, таких как:
"30-AUG-2015 +1 days# 30-AUG-2015 +2 days# 30-AUG-2015 +3 days#..."
Затем этот список зацикливается и передается в date
, где я могу grep
указать день, который я ищу, (, например. Сб ). Наконец, я могу использовать xargs
для преобразования вывода в формат, который вы ищете. Для удобства код можно поместить в одну строку.
MON=1
TUE=2
WED=3
THU=4
FRI=5
SAT=6
SUN=7
echo "Today " && date
echo "Next Monday " && date -d "+ $(( ( (6 + $MON - $(date +%u)) % 7) + 1 )) days"
echo "Next Tuesday " && date -d "+ $(( ( (6 + $TUE - $(date +%u)) % 7) + 1 )) days"
echo "Next Wednesday " && date -d "+ $(( ( (6 + $WED - $(date +%u)) % 7) + 1 )) days"
echo "Next Thursday " && date -d "+ $(( ( (6 + $THU - $(date +%u)) % 7) + 1 )) days"
echo "Next Friday " && date -d "+ $(( ( (6 + $FRI - $(date +%u)) % 7) + 1 )) days"
echo "Next Saturday " && date -d "+ $(( ( (6 + $SAT - $(date +%u)) % 7) + 1 )) days"
echo "Next Sunday " && date -d "+ $(( ( (6 + $SUN - $(date +%u)) % 7) + 1 )) days"
Выход
Today
Thu, Nov 12, 2020 10:24:38 PM
Next Monday
Mon, Nov 16, 2020 10:24:39 PM
Next Tuesday
Tue, Nov 17, 2020 10:24:40 PM
Next Wednesday
Wed, Nov 18, 2020 10:24:40 PM
Next Thursday
Thu, Nov 19, 2020 10:24:41 PM
Next Friday
Fri, Nov 13, 2020 10:24:42 PM
Next Saturday
Sat, Nov 14, 2020 10:24:42 PM
Next Sunday
Sun, Nov 15, 2020 10:24:43 PM
Пояснение
Идея состоит в том, чтобы рассчитать количество дней до следующего дня недели и добавить это число к текущей дате. Возьмем в качестве примера субботу.
Таким образом, первая итерация алгоритма выглядит следующим образом: берем текущий день недели date +%u
, берем mod 7
и добавляем 1
, потому что модуль основан на нуле:
( $(date +%u) % 7) + 1
Однако он не принимает во внимание, что наша последовательность дней для добавления является убывающей (5,4,3,2,1,7,6 ). Для этого нам нужно вычесть текущий день недели из 7
, затем взять по модулю и прибавить1
:
( (7 - $(date +%u)) % 7) + 1
Итак, мы получили рабочий пример для понедельника(7 == 6 + $MON
). Чтобы он искал любую неделю дня, мы должны переписать -как
( (6 + <DAY> - $(date +%u)) % 7) + 1
где <DAY>
должна быть любой из переменных выше($MON
...$SUN
)
Alpine Linux не поддерживает -d "+ 3 days"
, поэтому вы либо устанавливаете coreutils
(apk add coreutils
), чтобы заставить его работать, либо сами выполняете арифметические расчеты дней.
date -d "@$(($(date +%s) + 86400 * $(( ( (6 + $SAT - $(date +%u)) % 7) + 1 )) ))"
Пояснение
$(date +%s)
выводит количество секунд, прошедших с... знаете ли! 86400
количество секунд в день, date -d "@<number_of_seconds>"
восстанавливает дату из измененного количества секунд.
Работает как "Модификация для Alpine Linux" за исключением MacOS, вместо date -d "@<number_of_seconds>"
пишется date -r "<number_of_seconds>"
, поэтому
date -r "$(($(date +%s) + 86400 * $(( ( (6 + $SAT - $(date +%u)) % 7) + 1 )) ))"
Дополнительные сведения см. в разделе «Модификация для Alpine Linux/Пояснение» выше.
Гораздо проще написать решение::
$ adate1="30-AUG-2015"
$ faketime "$adate1" date -d 'saturday' +'%d-%b-%Y'
05-Sep-2015
Конечно, нужно установить faketime.