Стандарт sed не может назвать оболочку (GNU sed имеет расширение, чтобы сделать это, если Вы только заботитесь о невстроенном Linux), таким образом, необходимо будет сделать часть обработки снаружи sed. Существует несколько решений; все требуют тщательного заключения в кавычки.
Не ясно точно, как Вы хотите, чтобы значения были расширены. Например, если строка
foo hello; echo $(true) 3
каким из следующего должен быть вывод?
k=<foo> value=<hello; echo 3>
k=<foo> value=<hello; echo 3>
k=<foo> value=<hello; echo 3>
k=<foo> value=<foo hello
3>
Я буду обсуждать несколько возможностей ниже.
Можно заставить оболочку читать вход линию за линией и обрабатывать его. Это - простое решение и также самое быстрое для коротких файлов. Это - самая близкая вещь к Вашему требованию “echo \2
”:
while read -r keyword value; do
echo "k=<$keyword> v=<$(eval echo "$value")>"
done
read -r keyword value
наборы $keyword
к первому разграниченному пробелом слову строки, и $value
к остальной части строки минус запаздывающий пробел.
Если Вы хотите развернуть ссылки на переменную, но не выполнить команды вне замен команды, поместить $value
в здесь документе. Я подозреваю, что это - то, что Вы действительно искали.
while read -r keyword value; do
echo "k=<$keyword> v=<$(cat <<EOF
$value
EOF
)>"
done
Можно преобразовать вход в сценарий оболочки и оценить это. Sed до задачи, хотя дело не в этом легкий. Движение с “echo \2
” требование (отмечают, что мы должны выйти из одинарных кавычек в ключевом слове):
sed -e 's/^ *//' -e 'h' \
-e 's/[^ ]* *//' -e 'x' \
-e 's/ .*//' -e "s/'/'\\\\''/g" -e "s/^/echo 'k=</" \
-e 'G' -e "s/\n/>' v=\\</" -e 's/$/\\>/' | sh
Идя с сюда документом, мы все еще должны выйти из ключевого слова (но по-другому).
{
echo 'cat <<EOF'
sed -e 's/^ */k=</' -e 'h' \
-e 's/[^ ]* *//' -e 'x' -e 's/ .*//' -e 's/[\$`]/\\&/g' \
-e 'G' -e "s/\n/> v=</" -e 's/$/>/'
echo 'EOF'
} | sh
Это - самый быстрый метод, если у Вас есть много данных: это не запускает отдельный процесс для каждой строки.
Те же методы мы использовали с работой sed с awk. Получающаяся программа значительно более читаема. Движение с “echo \2
”:
awk '
1 {
kw = $1;
sub(/^ *[^ ]+ +/, "");
gsub(/\047/, "\047\\\047\047", $1);
print "echo \047k=<" kw ">\047 v=\\<" $0 "\\>";
}' | sh
Используя здесь документ:
awk '
NR==1 { print "cat <<EOF" }
1 {
kw = $1;
sub(/^ *[^ ]+ +/, "");
gsub(/\\\$`/, "\\&", $1);
print "k=<" kw "> v=<" $0 ">";
}
END { print "EOF" }
' | sh
Вы могли попробовать этот подход:
input='
keyword value value
keyword "value value"
keyword `uname`
'
process() {
k=$1; shift; v="$*"
printf '%s\n' "k=<$k> v=<$v>"
}
eval "$(printf '%s\n' "$input" | sed -n 's/./process &/p')"
(если я разбираюсь в Вашем намерении). Это - вставка "процесс" в начале каждой непустой строки для создания этого сценарием как:
process keyword value value
process keyword "value value"
process keyword `uname`
быть оцененным (eval
) где процесс является функцией, которая печатает ожидаемое сообщение.
Если non-sed решение будет приемлемо, то этот отрывок Perl сделает задание:
$ echo "$input" | perl -ne 'chomp; /^\s*(.+?)\s+(.+)$/ && do { $v=`echo "$2"`; chomp($v); print "k=<$1> v=<$v>\n"}'
Имея GNU sed
, вы можете использовать следующую команду:
sed -nr 's/([^ ]+) (.*)/echo "\1" \2\n/ep' input
Которая выводит:
keyword value value
keyword value value
keyword Linux
с вашими входными данными.
Объяснение:
Команда sed подавляет регулярный вывод с помощью опции -n
. -r
передается для использования расширенных регулярных выражений, что избавляет нас от экранирования специальных символов в шаблоне, но это не обязательно.
Команда s
используется для передачи строки ввода в команду:
echo "\1" \2
Ключевое слово get's цитирует значение not. Я передаю опцию e
- которая специфична для GNU - команде s
, которая говорит sed выполнить результат подстановки как команду оболочки и прочитать результаты в буфер шаблона (даже несколько строк). Использование опции p
после(!) e
заставляет sed
печатать буфер шаблонов после выполнения команды.
SOLO BESO CORTO SED PURO
Haré esto
echo "ls_me" | sed -e "s/\(ls\)_me/\1/e" -e "s/to be/continued/g;"
y funcionando.