Groovy и повседневные скрипты

· На чтение уйдёт 2 минуты · (297 слов)

Традиционно, уже много-много лет, ещё с 1999 года, кажется, для повседневных мелких задач по экстракции или обработке данных я использую Perl. Не сказать, что я за это время стал мега-супер-гуру, но могу написать такой скрипт, от прочтения которого у непосвящённого человека снесёт кукушечку.

Именно благодаря Perl, не сносит кукушечку у меня, в общем-то Java’иста, когда я смотрю на чьи-то творения на JavaScript, или того хуже, на каких-нибудь Erlang или Scala. Perl вообще подходящий язык для того, чтобы тренировать кукушечку, я считаю. Тем более, если им заниматься 12 лет.

Сегодня решил-таки сделать скриптец на Groovy. Причём именно что такой скриптец, который почти идеально смотрелся бы на perl.

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

Вот так выглядел бы скрипт на perl:

while (<FILE>) {
  if (/pattern1/) { s/this/that/ }
  elsif (/pattern2/) { s/this/that/ }
}

А вот так он выглядел бы на Groovy:

new File("dedede.sql").eachLine { line ->
  if (line=~/pattern1/) { line.replaceAll('this', 'that') }
  else if (line=~/pattern2/) { line.replaceAll('this', 'that') }
}

Но есть один нюанс: в Perl есть служебные переменные вида $1, $2, $3. А в Groovy их нет, но эти данные можно получить из матчера:

def matcher = line =~ /pattern1/; println matcher.group(1), matcher.group(2), matcher.group(3)

Как-то уже не вполне компактно получается. Но что самое плохое, нельзя написать что-то вроде:

new File("dedede.sql").eachLine { line ->
  if (def matcher=line=~/pattern1/) { line.replaceAll('this', matcher.group(3)) }
  else if (def matcher=line=~/pattern2/) { line.replaceAll('this', matcher.group(8)) }
}

Производительность скрипта для меня была не слишком важна, поэтому я матчил все строчки со всеми четырьмя регэкспами, хотя решение на перле матчило бы строчки в среднем с двумя регэкспами. Вообще такая несправедливость меня не слишком-то устраивает, буду искать решение самостоятельно и на StackOverflow.

Полезное