использование awk для создания точных совпадений

я просто задаюсь вопросом, как мы можем использовать awk, чтобы сделать точные совпадения.

для, например,

$ cal 09 09 2009
   September 2009
Su Mo Tu We Th Fr Sa
   1  2  3  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



$ cal 09 09 2009 | awk '{day="9"; col=index($0,day); print col }'
17
0
0
11
20
0
8
0

Поскольку Вы видите, что вышеупомянутая команда производит индекс всех строк, которые содержат строку/число "9", есть ли способ сделать выходной индекс awk только в 4-й строке вывода cal выше.??? может быть еще более изящное решение?

Я использую awk для получения дневного имени с помощью команды cal. вот целая строка кода:

     $ dayOfWeek=$(cal $day $month $year | awk '{day='$day'; split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", array); column=index($o,day); dow=int((column+2)/3); print array[dow]}')

Проблема с вышеупомянутым кодом состоит в том, что, если несколько соответствий найдены затем, я получаю несколько результатов, тогда как я хочу, чтобы он произвел только один результат.

Спасибо!

0
задан 07.03.2011, 21:23

4 ответа

Вы могли grep вывод cal только дать Вам одну строку:

$ cal 09 09 2009 | grep -E '(^9 | 9 | 9$)' | awk ...

grep соответствует одному из:

  • 9, сопровождаемые пространством в начале строки
  • 9 окружаются пробелами
  • Пространство, сопровождаемое 9 в конце строки.

Как то, что работа для Вас?

0
ответ дан 27.11.2019, 18:14

Я сделал бы это с чем-то как

dayOfWeek="$(cal $month $year |
             awk -v day=$day \
                'BEGIN {split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", days)}
                 NR > 2 {for (i = 1; i <= NF; i++) {if ($i == day) {print days[i]}}}')"

Здесь, BEGIN выполняется в запуске для установки days массив; другой шаблон включает строки 2 и (пропускающий заголовок), шаги через столбцы, пока он не находит day, и затем использует номер столбца для поиска рабочего дня. $ в awk оператор ссылки поля; так же, как $1 первое поле, $n поле, пронумерованное значением n. Я также передаю $day от оболочки до сценария с присвоением в начале awk строка. NR рекордное число (номер строки); NF количество полей на строке. (Можно установить RS и FS, соответственно, для изменения, что разделяет записи и поля, соответственно.)

(Новые строки обратной косой черты и новая строка после канала | только для ясности и заставить его не прокрутить слишком много.)

На этот раз это тестируется.

0
ответ дан 27.11.2019, 18:14

сценарий на этой странице делает просто это

http://www.computing.net/answers/unix/find-the-day-of-week-using-awk/5243.html

0
ответ дан 27.11.2019, 18:14

Дайте этому попытку:

cal 09 2009 | awk -v "num=9" '
    BEGIN {
        OFS="\t";
        day=" ?[^0-9]" num "([^0-9]|$)"
    }
    NR==2 {dow = $0}
    $0 ~ day {
        col=match(" " $0, day);
        print $0, col, substr(dow,col,2)
    }'

Все на одной строке:

cal 09 2009 | awk -v "num=9" 'BEGIN {OFS="\t"; day=" ?[^0-9]" num "([^0-9]|$)"} NR==2 {dow = $0} $0 ~ day {col=match(" " $0, day); print $0, col, substr(dow,col,2) }'

Демонстрация:

$ for i in {1..30}; do cal 09 2009 | awk -v "num=$i" 'BEGIN {OFS="\t"; day=" ?[^0-9]" num "([^0-9]|$)"} NR==2 {dow = $0} $0 ~ day {col=match(" " $0, day); print $0, num, col, substr(dow,col,2) }'; done
       1  2  3  4  5    1       7       Tu
       1  2  3  4  5    2       10      We
       1  2  3  4  5    3       13      Th
       1  2  3  4  5    4       16      Fr
       1  2  3  4  5    5       19      Sa
 6  7  8  9 10 11 12    6       1       Su
 6  7  8  9 10 11 12    7       4       Mo
 6  7  8  9 10 11 12    8       7       Tu
 6  7  8  9 10 11 12    9       10      We
 6  7  8  9 10 11 12    10      13      Th
 6  7  8  9 10 11 12    11      16      Fr
 6  7  8  9 10 11 12    12      19      Sa
13 14 15 16 17 18 19    14      4       Mo
13 14 15 16 17 18 19    15      7       Tu
13 14 15 16 17 18 19    16      10      We
13 14 15 16 17 18 19    17      13      Th
13 14 15 16 17 18 19    18      16      Fr
13 14 15 16 17 18 19    19      19      Sa
20 21 22 23 24 25 26    21      4       Mo
20 21 22 23 24 25 26    22      7       Tu
20 21 22 23 24 25 26    23      10      We
20 21 22 23 24 25 26    24      13      Th
20 21 22 23 24 25 26    25      16      Fr
20 21 22 23 24 25 26    26      19      Sa
27 28 29 30             28      4       Mo
27 28 29 30             29      7       Tu
27 28 29 30             30      10      We

Вот улучшение на сценарии что Mohamed, связанный с:

cal 09 2009 | awk -v "d=9" 'NR==2 {split($0, dow)} NR == 3 {print $0, d, dow[7 - ($NF + 35 - d) % 7]}'

Нет никакой потребности в head, tail или набор if операторы.

0
ответ дан 27.11.2019, 18:14

Теги

Похожие вопросы