Awk: найти блок кода внутри блока enum в файле заголовка

GNUawkрешение:

Образецtest.log:

95.108.181.102 - - [11/Feb/2018:11:43:10 +0000] "GET /blog/ HTTP/1.1" 200 4438 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" "-"
95.108.181.102 - - [11/Aug/2017:11:43:10 +0000] "GET /blog/ HTTP/1.1" 200 4438 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" "-"
95.108.181.102 - - [01/Jan/2018:11:43:10 +0000] "GET /blog/ HTTP/1.1" 200 4438 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" "-"
95.108.181.102 - - [11/Feb/2018:11:43:10 +0000] "GET /blog/ HTTP/1.1" 200 4438 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" "-"

awk -v m1_ago=$(date -d"-1 month" +%s) \
'BEGIN{ 
     split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", month);
     for (i in month) m_nums[month[i]] = i
 }
 { split(substr($4,2), a, "[/:]") }
 mktime(sprintf("%d %d %d %d %d %d", a[3], m_nums[a[2]], a[1], a[4], a[5], a[6])) > m1_ago
' test.log > tmp_log && mv tmp_log test.log

Окончательное test.logсодержание:

95.108.181.102 - - [11/Feb/2018:11:43:10 +0000] "GET /blog/ HTTP/1.1" 200 4438 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" "-"
95.108.181.102 - - [11/Feb/2018:11:43:10 +0000] "GET /blog/ HTTP/1.1" 200 4438 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" "-"
1
14.08.2019, 13:30
2 ответа

Практически никогда не стоит возиться с регулярными выражениями в синтаксисе любого языка. Он очень хрупок и может закончиться хаосом по малейшей причине, такой как закомментированная строка #ifdef. Исправление глючного парсера другим потенциально глючным парсером — это… как минимум странно.

Если вы поняли проблему, вы можете продолжить чтение.

В некоторых случаях это может помочь удалить весь блок #ifdef(, кстати, вы уверены, что хотите рассматривать его как не определенный?):

sed '/ enum /,/}/!b
  /#ifdef/!b
  :loop
  N
  /#endif/!bloop
  d' file.h

Пояснение:

  • / enum /,/}/!bоставить все строки вне диапазонаenum-}-нетронутыми
  • /#ifdef/!bтакже оставьте все внутри нетронутым, пока#ifdef
  • :loopда, как только мы встретили #ifdef, нам нужно зациклиться
  • NТеперь начинаем дописывать строки...
  • /#endif/!bloopпока не нашли#endif
  • Затем dудалите все, что мы собрали между #ifdefи #endifмы собрали
1
27.01.2020, 23:15

awkможно сделать это с помощью диапазонов и флага, например:

awk '/enum fixedsample/,/} FIXEDNAME/ { e=1 } e && /^#ifdef/,/^#endif/ { next } { e=0; print }' foo.hpp

Версия sedдаже не нуждается в флаге, просто вложите диапазоны, поэтому каждый #ifdef... #endifдиапазон внутри диапазона enum... }dудаляется:

sed '/enum fixedsample/,/} FIXEDNAME/{; /^#ifdef/,/^#endif/d; }' foo.hpp

В текущей версии следует использовать более точные шаблоны, чтобы снизить вероятность ложных срабатываний.

4
27.01.2020, 23:15

Теги

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