Не глядя на точное окружение, я могу только предположить, что / tmp не существует (или заполнен, или имеет некоторую проблему с правами доступа) на виновной машине. Когда вы пишете в существующий файл, vim не может сохранить резервную копию, поэтому он жалуется, а затем предлагает вам.
Вы можете проверить, так ли это, попробовав одно из следующего:
: w!
. Посмотрите, можете ли вы получить сообщение об ошибке перед запросом, добавив это в .vimrc
:
set cmdheight = N
Попробуйте N = 2 или 3 или 4 в зависимости от того, что подходит для вашей среды.
Я получил последний день предыдущего месяца следующим образом:
cal $month $year | awk 'NF {DAYS = $NF}; END {print DAYS}'
Используя переменные заполнители, я могу получить календарь предыдущих месяцев и распечатать последний день месяца:
cal 04 2017 | awk 'NF {DAYS = $NF}; END {print DAYS}'
Вывод:
30
Если есть более простой или короткий путь, пожалуйста, я открыт для всех предложений.
Попробуйте:
eval "$(
LC_ALL=C perl -MPOSIX -le '
@t = localtime;
$t[3]=0; # set day to 0 (day before the first)
print strftime q(year=%Y month=%m day=%d month_abv="%b"), @t'
)"
perl
создает некоторый шелл-код (например, year=2017 month=04 day=30 month_abv="Apr"
), который мы затем вычислим
включим в текущую оболочку (предполагая оболочку POSIX).
LC_ALL=C
означает принудительное отображение абзаца месяца на английском языке независимо от локали. Удалите его, если вы предпочитаете, чтобы он был в локали пользователя.
Этот трюк day=0
работает с strftime()
GNU, FreeBSD и Solaris, но я не знаю, насколько он переносим вне этого.
Чтобы получить первый день предыдущего месяца, замените $t[3]=0
на $t[3]=1; $t[4]--
, который для меня работает, даже если он запущен в январе, но опять же, я не уверен, насколько он переносим.
Похоже, что нижеприведенное работает нормально для меня на ksh88 (спасибо Stéphane Chazelas за некоторую помощь в этом)
#! /bin/ksh
eval "$(date +'y=%Y m=%m')"
echo "Current month = $m"
echo "Current year = $y"
#get previous month (and year of previous month)
if [[ $((m-1)) -gt 0 ]]
then
p_m=$((m-1))
p_m_y=$((y))
else
p_m=12
p_m_y=$((y-1))
fi
echo "p_m = $p_m"
echo "p_m_y = $p_m_y"
#get first/last day of previous month
p_m_from=01.${p_m}.${p_m_y}
p_m_to=$(cal $p_m $p_m_Y | grep -v ^$ | tail -1 | sed 's/^.* \([0-9]*\)$/\1/').${p_m}.${p_m_y}
echo "Previous month runs from $p_m_from to $p_m_to"
Вы можете вычислить один день до первого дня этого месяца, используя GNUdate
:
date -d "$(date +"%Y-%m-01") - 1 day" +"%F"
или используя dateutils
сdateadd
:
dateadd "$(date +"%Y-%m-01")" "-1d"
или немного сложное dateutils
использование. Округлить до последнего 31-го дня месяца. (Задокументировано поведение, которое работает даже в течение месяцев с менее чем 31 днем.)
$ dateround --next today -31d
2017-04-30
$ dateround --next "2016-03-10" -31d
2016-02-29
Чтобы найти предыдущий месяц, выполните следующие действия:
date -d "-1 months" +%Y/%-m/%-d
Это даст вам :2018/2/22
, пока есть 2018/3/22
.
date -d "-1 days" +%Y/%-m/%-d
Дам вам:2018/3/21
Вы можете добавить или вычесть сколько угодно месяцев или дней. Если вычесть достаточное количество месяцев, получится прошлый год.