Kornshell - Как правильно печатать пустые места
В настоящее время я использую эту команду,
cal $month $year | sed -n '1,2p'
cal $month $year | sed -n '3,$p' |
sed -n '/'$day'/{s/.*\('$day'.*\)/\1/p; :a; n; p; ba; }'
И это дает мне этот вывод
March 2014
Su Mo Tu We Th Fr Sa
4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Как я могу получить этот вывод?
March 2014
Su Mo Tu We Th Fr Sa
4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
FYI: $month $year $day
использует текущую дату. Я стараюсь избегать использования заданного количества пробелов, потому что если бы это был другой день, то цифры не совпали бы с пробелами.
РЕДАКТИРОВАТЬ: Для Джонатана Леффлера
Спасибо! Это очень близко к результату, который я ищу. Пример вывода, который вы опубликовали, именно то, что я ищу, но после того, как попробовал ваш код. Это дало мне это вместо этого.
March 2014
Su Mo Tu We Th Fr Sa
2 3 4 5 Q6 7 8
6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Как я могу удалить строку с Q? Я предполагаю, что это идет от 2-го s///
вы предоставили
РЕДАКТИРОВАТЬ:
Разберись, спасибо за помощь!
2 ответа
Этот скрипт работает (я думаю):
year=2014
month=3
day=6
cal $month $year | sed -n -e '
1,2p
3,${/'$day'/{
s/^\(.*\)\('$day'.*\)/\1Q\2/
:blanks
s/^\( *\)[^ Q]/\1 /g
t blanks
s/Q//p
:a
n
p
ba
}
}'
Образец вывода:
March 2014
Su Mo Tu We Th Fr Sa
6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
- Первый
s///
Команда ставит Q (не является частью вывода изcal
) до дня, который вы хотите сохранить. - Этикетка
:blanks
,s///
иt blanks
замените строку пробелов и непустой, non-Q строкой пробелов и другой пробел, заменяя все непустые символы перед Q. s/Q//p
удаляет маркер и печатает линию.- Остальная часть кода такая же, как и раньше (но распределена по нескольким строкам); он получает следующую строку ввода и печатает ее повторно.
awk
Скрипт для достижения желаемого эффекта:
cal.awk:
# Print first two lines (heading)
NR < 3 { print; next }
# Skip weeks in which the last day is before variable 'day'
$NF < day { next }
# Print full weeks if the first day is on or after variable 'day'
$1 >= day { print; next }
# This will be executed for the week on which variable 'day' falls.
{
# Traverse each day
for (i=1; i<=NF; ++i) {
# If current day is on or after variable 'day', print it.
if ($i >= day) {
if ($i < 10) # Check for extra formatting for single digit days
printf(" ");
printf("%d ", $i);
}
else
printf " "; # Formatting for blank days
}
print ""; # Add new line
}
Призвание:
cal $month $year | awk -v day=$day -f cal.awk