У меня есть «Я люблю Сьюзи и Жениться», и я хочу изменить «Сьюзи» на «Сара».
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
Результат должен быть таким:
firstString="I love Sara and Marry"
У меня есть «Я люблю Сьюзи и Жениться», и я хочу изменить «Сьюзи» на «Сара».
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
Результат должен быть таким:
firstString="I love Sara and Marry"
Ответы:
Чтобы заменить первое вхождение шаблона данной строкой, используйте :${parameter/pattern/string}
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"
# prints 'I love Sara and Marry'
Чтобы заменить все вхождения, используйте :${parameter//pattern/string}
message='The secret code is 12345'
echo "${message//[0-9]/X}"
# prints 'The secret code is XXXXX'
(Это отражено в в Bash Reference Manual , §3.5.3 "Shell Параметр Expansion" .)
Обратите внимание, что эта функция не указана в POSIX - это расширение Bash - поэтому не все оболочки Unix реализуют ее. Соответствующую документацию POSIX см. В разделе Базовые технические спецификации стандарта Open Group, выпуск 7 , том Shell & Utilities , §2.6.2 «Расширение параметров» .
\nв этом контексте будет представлять себя, а не перевод строки. Сейчас у меня нет возможности использовать Bash для тестирования, но вы должны написать что-то вроде $STRING="${STRING/$'\n'/<br />}". (Хотя вы, вероятно, хотите STRING//- заменить все - вместо просто STRING/.)
echo ${my string foo/foo/bar}. Тебе понадобитсяinput="my string foo"; echo ${input/foo/bar}
//непосредственного упоминания , в ней упоминается, что происходит, «если шаблон начинается с /« »(что даже не является точным, поскольку остальная часть этого предложения предполагает, что дополнительное на /самом деле не является частью шаблон) - но я не знаю лучшего источника.
Это можно сделать полностью с помощью манипуляции с bash:
first="I love Suzy and Mary"
second="Sara"
first=${first/Suzy/$second}
Это заменит только первое вхождение; чтобы заменить их все, удвойте первую косую черту:
first="Suzy, Suzy, Suzy"
second="Sara"
first=${first//Suzy/$second}
# first is now "Sara, Sara, Sara"
Для Dash все предыдущие посты не работают
POSIX- shсовместимое решение:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
result=$(echo $firstString | sed "s/Suzi/$secondString/g")
echoаргумента. Он обманчиво работает без кавычек с простыми строками, но легко разбивается на любую нетривиальную входную строку (неправильный интервал, метасимволы оболочки и т. Д.).
попробуй это:
sed "s/Suzi/$secondString/g" <<<"$firstString"
Лучше использовать bash, чем sedесли в строках есть символы RegExp.
echo ${first_string/Suzi/$second_string}
Он переносим на Windows и работает по крайней мере со старым, как Bash 3.1.
Чтобы показать, что вам не нужно беспокоиться о побеге, давайте обратимся к этому:
/home/name/foo/bar
В это:
~/foo/bar
Но только если /home/nameэто в начале. Нам не нужно sed!
Учитывая, что bash дает нам волшебные переменные $PWDи $HOMEмы можем:
echo "${PWD/#$HOME/\~}"
РЕДАКТИРОВАТЬ: Спасибо за Марк Haferkamp в комментариях за примечание о цитировании / экранирование ~. *
Обратите внимание, что переменная $HOMEсодержит косые черты, но это ничего не сломало.
Дополнительная информация: Расширенное руководство по написанию сценариев .
Если использование sedявляется обязательным, обязательно избегайте каждого символа .
sedс pwdкомандой , чтобы избежать определения новой переменной каждый раз , когда мои собственные $PS1пробеги. Предоставляет ли Bash более общий способ, чем магические переменные, использовать вывод команды для замены строки? Что касается вашего кода, мне пришлось избежать того, ~чтобы Bash не расширил его до $ HOME. Кроме того, что делает #в вашей команде?
~»: обратите внимание, как я цитировал материал. Не забывайте всегда цитировать вещи! И это работает не только для магических переменных: любая переменная способна к подстановкам, получению длины строки и многим другим в bash. Поздравляю с попыткой $PS1быстро: вам также может быть интересно, $PROMPT_COMMANDесли вам удобнее использовать другой язык программирования и вы хотите написать скомпилированное приглашение.
echo "${PWD/#$HOME/~}"не заменяет мой $HOMEна ~. Замена ~на \~или '~'работает. Любая из них работает на Bash 4.2.53 в другом дистрибутиве. Можете ли вы обновить свой пост, чтобы процитировать или избежать ~для лучшей совместимости? Под вопросом «магические переменные» я имел в виду следующее: могу ли я использовать подстановку переменных в Bash, например, на выходе, unameне сохраняя его сначала как переменную? Что касается моего личного $PROMPT_COMMAND, это сложно .
Если завтра вы решите, что не любите замуж, то ее тоже можно заменить:
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
Должно быть 50 способов расстаться с любовником.
Поскольку я не могу добавить комментарий. @ruaka Чтобы сделать пример более читабельным, напишите это так
full_string="I love Suzy and Mary"
search_string="Suzy"
replace_string="Sara"
my_string=${full_string/$search_string/$replace_string}
or
my_string=${full_string/Suzy/Sarah}
Чистый POSIX метод оболочки, который в отличии от Roman Kazanovskyi «s sed-На ответа не требует никаких внешних инструментов, только собственные родные оболочечных расширения параметров . Обратите внимание, что длинные имена файлов сведены к минимуму, поэтому код лучше помещается в одну строку:
f="I love Suzi and Marry"
s=Sara
t=Suzi
[ "${f%$t*}" != "$f" ] && f="${f%$t*}$s${f#*$t}"
echo "$f"
Вывод:
I love Sara and Marry
Как это работает:
Удалите самый маленький шаблон суффикса. "${f%$t*}"возвращает " I love", если суффикс $t" Suzi*" находится в $f" ". I love Suzi and Marry
Но если t=Zelda, то "${f%$t*}"ничего не удаляет и возвращает всю строку " I love Suzi and Marry".
Это используется для проверки, если $tнаходится в $fс, [ "${f%$t*}" != "$f" ]который будет иметь значение true, если $fстрока содержит " Suzi*" и false, если нет.
Если тест возвращает истинный , построить нужную строку , используя Удалить Наименьший суффиксов Pattern ${f%$t*} « I love» и удалить Наименьший префикс Pattern ${f#*$t} « and Marry», с 2 - ой строке $s« Sara» между ними.
Я знаю, что это старый, но так как никто не упомянул об использовании awk:
firstString="I love Suzi and Marry"
echo $firstString | awk '{gsub("Suzi","Sara"); print}'
echo [string] | sed "s/[original]/[target]/g"