Ответ 1
Если вы создаете свой текст с несколькими строками с помощью "\n
", это будет работать с простой командой sed
как:
DATA=`echo ${DATA} | tr '\n' "\\n"`
#now, DATA="line1\nline2\nline3"
sed "s/_data_/${DATA}/" mail.tpl
Я работаю над bash - script, который должен подготовить E-Mail для отправки пользователю.
Он объединяет некоторые данные, которые заканчиваются несколькими строками. Для примера, хранящегося в $DATA
.
Теперь, после немного stfw, я нашел несколько вещей, таких как sed -ei "s/_data_/${DATA}/g" mail.tpl
, а также sed заменить переменной несколькими строками. Ни один из них не работает.
Теперь возникает вопрос: как мне получить sed
, чтобы заменить что-то несколькими строками текста?
(Альтернативы sed
также приветствуются!)
Если вы создаете свой текст с несколькими строками с помощью "\n
", это будет работать с простой командой sed
как:
DATA=`echo ${DATA} | tr '\n' "\\n"`
#now, DATA="line1\nline2\nline3"
sed "s/_data_/${DATA}/" mail.tpl
Вы можете сделать это с помощью AWK, используя подстановку переменных. Мы можем установить переменную в AWK, используя -v
, а затем использовать функцию AWK gsub
чтобы заменить все вхождения регулярного выражения этой переменной.
Например, если файл test
имеет следующее содержимое...
foo
bar
blah _data_and_data_
foo
_data_ foobar _data_ again
... а переменная Bash $DATA
- это...
1
2
3
4
5
... затем awk -v r=$DATA '{gsub(/_data_/,r)}1' test
заменяет все вхождения регулярного выражения _data_
в test
файла содержимым $DATA
, что приводит к следующему:
foo
bar
blah 1
2
3
4
5and1
2
3
4
5
foo
1
2
3
4
5 foobar 1
2
3
4
5 again
Я попробовал его и sed 's/pattern/\na\nb\nc/g'
, но он не работает во всех системах. То, что работает, помещает \
, за которым следует новая строка в шаблоне замены, например:
sed 's/pattern/a\
b\
c/g'
Это добавляет строку, содержащую b
, и строку, содержащую c
, когда шаблон отображается.
Чтобы поместить его в переменную, используйте двойную обратную косую черту:
export DATA="\\
a\\
b\\
c"
а затем:
sed "s/pattern/${DATA}/g"
Обратите внимание на двойные кавычки.
Я бы предложил просто заменить sed на команду perl следующим образом:
perl -i.bak -pe 's/_data_/$ENV{"DATA"}/g' mail.tpl
Ответ на вызов кольца не помог мне; Я думаю, что использование tr
не так, и способ, которым он был написан, он просто удаляет новые строки с помощью echo
.
Вместо этого я использовал sed
. Я использовал код из другого ответа для замены новых строк (кредит: Zsolt Botykai). Я также ожидал, что на моем входе появятся знаки доллара ($
), поэтому я тоже позаботился об этом. Возможно, вам придется добавить другую обработку ввода. Обратите внимание на использование двойных кавычек в echo
для сохранения новых строк.
DATA="$(cat whatever)"
ESCAPED_DATA="$(echo "${DATA}" | sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/\$/\\$/g')"
Затем вы можете использовать ${ESCAPED_DATA}
в sed
:
cat input | sed 's/one liner/'"${ESCAPED_DATA}"'/' > output
Просто подумал, что я поделюсь.
Эхо-переменная во временный текстовый файл.
Вставьте текстовый файл в mail.tpl и удалите данные из mail.tpl
echo ${DATA} > temp.txt
sed -i -e "/_data_/r temp.txt" -e "//d" mail.tpl
Сброс всех новых строк с помощью \
(кроме последнего) работал на меня.
Последнюю новую строку нельзя экранировать, чтобы не разорвать команду s
.
Пример:
DATA="a
b
c"
ESCAPED=$(echo "${DATA}" | sed '[email protected][email protected]\\@g')
echo "${ESCAPED}"
a\
b\
c
sed "s/pattern/${ESCAPED}/" file
Вы можете поместить свои данные в файл temp и запустить:
$ sed '/_data_/r DATA_FILE' mail.tpl | sed '/_data_/d'> temp; mv temp mail.tpl
Не уверен, что вы попытались поместить "\n" в заменяемую часть
sed 's/[pattern]/\
[line 1]\n\
[line 2]\n\
[line n]\n\
/g' mail.tpl
В первой строке есть /\ для удобства чтения. Каждая строка после этого представляет собой отдельную строку, подобную той, которую вы найдете в текстовом редакторе. Последняя строка является автономной, еще раз для удобства чтения. Вы можете сделать все это, если нужно. Работает на Debian Jessie, когда я его тестировал.