У меня есть выражение формы @(<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"