2015-07-14 1 views
1

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

select * from foo where ts>@(-2 days) and ts < @(-1 hour) 

(это, конечно, просто пример, который я хочу, чтобы поддержать любую конструкцию запроса и любые выражение @())

Я хочу заменить выражение в каждом @() с результатом оценки date --date=exp +%s, где ехр 'является выражение (так в приведенном выше примере результат будет

select * from foo where ts>1436694136 and ts < 1436863336 

Как правило, как заменить шаблон результатом вызова команды оболочки с захватами из шаблона в качестве аргументов?

(я меченый вопрос с Perl, и Баш, но я открыт к чему-либо)

ответ

1

Использование гну SED:

$ sql_expr="select * from foo where ts>@(-2 days) and ts < @(-1 hour)" 

$ sed -r 's|@\(([^)]*)\)|$(date +%s --date "now\1")|g; s|.*|echo "&"|e' <<< "$sql_expr" 

Gave: 
select * from foo where ts>1436696209 and ts < 1436865409 

Обратите внимание, что в этом коде предполагается, что содержимое @(...) является допустимым выражением для расчета даты.

Объяснение:

  1. Первое выражение заменит все вхождения @() с $(date +%s --date "now _expression_") где _expression_ будет что-то вроде -2 days.
  2. Second replace expression добавляет echo "..." вокруг всей строки & выполняет сгенерированную строку. Вы можете удалить флаг e во втором выражении, чтобы узнать, какая команда выполняется на самом деле.
1

Что-то, как показано ниже (непроверенные)

#!/usr/bin/perl 
use strict; 
use warnings; 
my $date1; 
my $date2; 
my $expr = q{select * from foo where ts>@(-2 days) and ts < @(-1 hour)}; 
if($expr =~ m#\@\((.*?)\) and .*? \@\((.*?)\)#){ 
    $date1 = $1; 
    $date2 = $2; 
} 
my $expr1 = `date --date=$date1 +%s`; 
my $expr2 = `date --date=$date2 +%s`; 

#now search and replace the $expr 

$expr =~ s#\@\((.*?)\)#$expr1; 
$expr =~ s#< \@\((.*?)\)#<.$expr2; 

print "Final expression is $expr\n"; 
Смежные вопросы