У меня есть "Я люблю 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, том "Шлюз и утилиты", §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"
Лучше использовать 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
является обязательным, обязательно избегайте каждого символа.
sed
с командой pwd
чтобы избежать определения новой переменной каждый раз, когда запускается мой пользовательский $PS1
. Предоставляет ли Bash более общий способ, чем магические переменные, использовать вывод команды для замены строки? Что касается вашего кода, мне пришлось уйти от ~
чтобы Bash не расширил его до $ HOME. Кроме того, что делает #
в вашей команде?
~
": обратите внимание, как я цитировал материал. Не забывайте всегда цитировать вещи! И это работает не только для магических переменных: любая переменная способна к подстановкам, получению длины строки и многому другому в bash. Поздравляю с попыткой быстро $PROMPT_COMMAND
$PS1
: вас также может заинтересовать $PROMPT_COMMAND
если вам удобнее использовать другой язык программирования и вы хотите $PROMPT_COMMAND
скомпилированное приглашение.
Для Dash все предыдущие сообщения не работают
Совместимое с POSIX sh
решение:
result=$(echo "$firstString" | sed "s/Suzi/$secondString//")
result=$(echo $firstString | sed "s/Suzi/$secondString/g")
Если завтра вы решите, что не любите Marry, ее тоже можно заменить:
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
Должно быть 50 способов оставить своего любовника.