У меня есть "Я люблю Suzi и Marry", и я хочу изменить "Suzi" на "Sara".
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
Результат должен быть таким:
firstString="I love Sara and Marry"
У меня есть "Я люблю Suzi и Marry", и я хочу изменить "Suzi" на "Sara".
#!/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, §3.5.3 "Расширение параметров оболочки".)
Обратите внимание, что эта функция не указана в POSIX - это расширение Bash - поэтому не все оболочки Unix реализуют ее. Соответствующую документацию по POSIX см. В разделе Базовые технические характеристики стандарта Open Group, выпуск 7, том Shell & Utilities, §2.6.2 "Расширение параметров".
Это можно сделать полностью с помощью 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"
попробуйте следующее:
sed "s/Suzi/$secondString/g" <<<"$firstString"
Для Dash все предыдущие посты не работают
Совместимое решение POSIX sh
:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
Лучше использовать 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/\~}"
EDIT: Спасибо за Марка Хаферкампа в комментариях к заметке о цитировании/побеге ~
. *
Обратите внимание, как переменная $HOME
содержит слэши, но это ничего не сломало.
Дальнейшее чтение: Расширенный Bash-Scripting Guide.
Если использование sed
является обязательным, обязательно избегайте каждого символа.
Если завтра вы решите, что не любите Marry, ее тоже можно заменить:
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, который, в отличие от ответа Романа Казановского sed
-based, не нуждается во внешних инструментах, только в собственных расширениях собственных параметров оболочки. Обратите внимание, что длинные имена файлов сведены к минимуму, поэтому код лучше помещается в одну строку:
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, если нет.,
Если тест возвращает значение true, создайте нужную строку, используя команду "Удалить наименьший суффикс" ${f%$t*}
" I love
" и "Удалить наименьший префикс" ${f#*$t}
" and Marry
" со второй строкой $s
" Sara
" между ними.
Я знаю, что это старый, но так как никто не упомянул об использовании awk:
firstString="I love Suzi and Marry"
echo $firstString | awk '{gsub("Suzi","Sara"); print}'
Вы можете использовать функцию str_replace()