Оценить часть текстовой строки

Оценить часть текстовой строки

У меня есть выражение формы @(<date calculation>), которое я хочу заменить на результат date +%s --date "now<date calculation>". Так, например, @(-1 day)будет заменено на результат date +%s --date "now -1 day".

Выражение встроено в строку текста, и у меня их может быть несколько. Например echo hi @(-1 day) bye "@(-1 hour)", . Результат оценки должен быть чем-то вроде echo hi 1491848561 bye "1491931365". Поэтому я хочу, чтобы оценивалось только выражение, и ничего больше.

Я попробовал использовать команду GNU sed 'e':, sed -r 's|@\(([^)]*)\)|date +%s --date "now\1"|e'но она оценивает всю строку, а не только замененное выражение.

Я не привязан к использованию sed, поэтому любые другие предложения приветствуются, но мне интересно, как заставить sed работать, для общего понимания.

решение1

Насколько мне известно, eмодификатор GNU sed всегда передает все пространство шаблонов оболочке, и эта оболочка всегда/bin/sh

Возможно, вам повезет больше, если вы используете perl, например,

$ echo 'For example echo hi @(-1 day) bye "@(-1 hour)"' | 
    perl -pe 's/@\((.*?)\)/sprintf "%s", $d = `date +%s --date "now $1"`, chomp $d/ge'
For example echo hi 1491874845 bye "1491957645"

(в отличие от sed, perl eмодификатор, по-видимому, не удаляет завершающий символ новой строки из вывода команды оболочки — отсюда и chomp).

Однако, если вы собираетесь использовать perlего, то, вероятно, предпочтительнее будет воспользоваться одним из доступных модулей для выполнения манипуляций с датами, например

$ echo 'For example echo hi @(-1 day) bye "@(-1 hour)"' | 
    perl -MDate::Manip=ParseDateDelta,UnixDate -pe 's/@\((.*?)\)/UnixDate(ParseDateDelta($1), "%s")/ge'
For example echo hi 1491875065 bye "1491957865"

Связанный контент