2015-03-16 1 views
1

@UnixКак захватить первый вторнику в месяц с нулями в Unix

Я пытаюсь захватить первый вторник каждого месяца в переменную и пытается площадку Ноль против него без удачи.

Ниже кусок кода, который я пробовал:

cal | sed -e 's/ \([1-9]\) /0\1 /g' -e 's/ \([1-9]\)$/0\1/' | awk 'NR>2{Sfields=7-NF; if (Sfields == 0) {printf "%d\n",$3;exit}}' 

Может кто-то помочь мне, что я здесь отсутствует?

+2

возможно, некоторые ввода образца (в вашем environnment) и ожидается, вывод ? – NeronLeVelu

ответ

0

Я думаю, что получил ответ.

cal | awk 'NR>2{Sfields=7-NF; if (Sfields == 0) {printf "%02d\n",$3;exit}}' 

Вышеуказанное заявление будет сделано. "%02d" делает это для меня

+0

Это не все месяцы, когда первый вторник первый или второй месяц. Посмотрите на 'cal -m6'. Ваше решение дает '09', правильно' 02' – Jotne

1
# for monday calendar 
cal -m1 | sed -n '1,2b;/^.\{3\} \{0,1\}\([0-9]\{1,2\}\) .*/ {s//0\1/;s/.*\([0-9]\{2\}\)$/\1/p;q;}' 
# for sunday calendar 
cal -s1 01 01 2015 | sed -n '1,2b;/^.\{6\} \{0,1\}\([0-9]\{1,2\}\) .*/ {s//0\1/;s/.*\([0-9]\{2\}\)$/\1/p;q;}' 
  • cal вариант зависит от системы (проверено здесь на Red Hat 6.6) и средний -m понедельник в первый день и -s на воскресенье (прилагаемое 1 за 1 месяц дисплей). Возьмите линию согласно указанному выходу cal.
  • не выводятся на печать строки по умолчанию
  • не заботятся линии 1 и 2
  • тейк линии с непустым второй (третьей)/группы
  • взять второй (/ третья) группа (положение) число до следующего и заменить на 0, удалить trailng символ
  • взять 2 последнюю цифру первой группы, удалите оставшуюся и распечатать его
  • бросить курить (никакая другая линия)

ТНА НКС к @Jotne для всех замечание о первой хотел день в течение второй недели (четвёртая линия, а не 3-я) и первый день недели

+0

Не работает, попробуйте 'cal -m 1 | sed -n '3 {s/* [0-9] * */0 /; s/[0-9] * \ ([0-9] \ {2 \} \). */\ 1/p; } ''должен давать' 06', но дает '02'. EDIT, дает '02' за любой месяц. – Jotne

+0

вправо, приспособить ответ для этого – NeronLeVelu

+0

Все еще неправильно. Первый вторник в январе - '06' не' 05', так как выдает вывод вашей строки. Я всегда отправляю вывод своей команды, если она не длинная. Легко видеть, правильно ли это или нет. – Jotne

1

Это awk должны сделать:

cal | awk 'NR>2 && NF>4 {printf "%02d\n",$(NF-4);exit}' 
03 

Чтобы подтвердить свою работу:

for i in {1..12}; do cal -m $i | awk 'NR>2 && NF>4 {printf "%02d\n",$(NF-4);exit}' ; done 
06 
03 
03 
07 
05 
02 
07 
04 
01 
06 
03 
01 

Или вы можете использовать ncal

ncal | awk '/Tu/ {printf "%02d\n",$2}' 
03 

Если вам нравится версия, где вы можете указать имя недели,
и будет работать, если Monday в первый день недели, то это gnu awk следует сделать:

cal | awk 'NR==2 {for (i=1;i<=NF;i++) {sub(/ /,"",$i);a[$i]=i}} NR>2 {if ($a["Tu"]~/[0-9]/) {printf "%02d\n",$a["Tu"];exit}}' FIELDWIDTHS="3 3 3 3 3 3 3 3" 
03 

Он использует FIELDWITH, чтобы убедиться, что пустые столбцы в начале месяца не изменяет выход.

0

Баш и дата.Может быть медленнее, чем разборе кал:

y=2015 
for m in {1..12}; do 
    for d in {01..07}; do 
     if [[ $(date -d "$y-$m-$d" +%w) -eq 2 ]]; then 
      echo $d 
      break 
     fi 
    done 
done 

Воплощение в AWK: будет быстрее, так как он не должен назвать дату несколько раз:

gawk -v y=2015 ' 
    BEGIN { 
     for (m=1; m<=12; m++) { 
      for (d=1; d<=7; d++) { 
       t = mktime(y " " m " " d " 12 0 0") 
       if (strftime("%w", t) == 2) { 
        printf "%02d\n", d 
        break 
       } 
      } 
     } 
    } 
' 
Смежные вопросы