Спрятать колонку

[AWK] Немного о языке

немного отойду от основной темы сиквела и друпала и покажу на примере какие возможности бывают сокрыты в скриптовых языках.
предметом небольшого погружения станет язык awk. это скриптовый язык с помощью которого можно разбирать потоки (файлы или их массив, пайпы), взаимодействовать с юзером и т.д.

передо мной встала задача - необходимо распарсить файл с набором скриптов, которые создают триггеры, фукнции, процедуры. общий шаблон имеет следующий вид:

delimiter $$
 
drop procedure if exists proc_name$$
 
create procedure proc_name
....
end
$$
 
delimiter ;

delimiter ;

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

первая часть задачки замечательно решается с помощью с помощью утилиты csplit. только выдрать имя файла у меня так и не получилось (хотя это и не означает, что этого нельзя сделать). на помощь, как всегда, пришел великий и ужасный гугл, который, кроме прочей ерунды, выдал на первую страницу ссылку на доки по этому замечательному языку.

язык умеет делать следующие штуки:
- парсит построчно или "постолбцово" входной поток;
- имеет встроенные функции;
- понимает regexp;
- может вызывать внешние скрипты;
- позволяет в процессе выполнения скрипта посылать запросы юзеру;
- язык процедурный;
это все что я за полдня успел откопать.

приведу прожку, которая решает поставленную задачу с небольшими комментариями:

BEGIN{
  # получение подкаталога для сохранения файлов
  print "Enter folder to place files:";
  getline folder < "-";
  print | "mkdir -p " folder ";";
  folder = folder "/";
  file = ""
  delimiter = 0;
}
{
  pos = index(tolower($0), " if exists ");
  # проверяем новая ли это процедура
  if (pos > 0) {
    dot = index($0, ".");
    # выделяем имя
    file = substr($0, dot + 1, length($0) - dot - 2);
    delimiter = 0;
    print "DELIMITER $$\n" > folder file ".sql";
  }
 
  if (file){
    # пишем в файл
    if (delimiter == 0){
      print $0 > folder file ".sql";
      delimiter = index(tolower($0), "delimiter");
    }
  }
}
END{
  print "done...."
}

и никаких сложностей. последний финт с delimiter отрубает хвостовые пустые строки в каждом скрипте.

deardron
16/01/2010 - 16:55
# 1

Да, это мощный язык, вместе с SED и GREP он позволяет юниксовскому шеллу творить чудеса.

В принципе, всё то же самое можно было сделать и на Perl. Он содержит все возможности, которые есть у AWK, да и синтаксис очень похожий.

Ворон
16/01/2010 - 17:05
# 2

deardron, а sed кажется интерактивный редактор да и синтаксис у него посложнее будет. на то чтобы написать эту программу с нуля потребовалось полчаса + 15 минут на то, чтобы найти мануал на gnu.

еще одна небольшая деталь.
мне показалось весьма интересным начать разбираться в новом языке (то, что он скриптовый - большой плюс, так как язык не сложный). есть желание сесть на bash, и как-нибудь добраться до функциональных языков, коих сейчас как грязи.

Вы, кстати, знаете еще-какие нибудь интересные языки, с вероятно узкой специализацией, но полезные и сегодня?

----------------------------------------------

live free or die...

deardron
16/01/2010 - 17:56
# 3

Нет, я к сожал. не очень интересуюсь всем многообразием языков... В мире Юниксов сейчас активно используются такие языки, как python и ruby, но я с ними не знаком Smile

Ворон
16/01/2010 - 18:04
# 4

deardron
python и ruby

неее, это языки программирования "широкого" профиля. меня больше мелкие да узкие интересуют, вроде awk. ну да ладно

----------------------------------------------

live free or die...

Наверх