@ruakh как мне написать это утверждение с условием или. Просто, если я хочу заменить Сьюзи или Жениться на новую строку.
Priyatham51
3
@ Priyatham51: для этого нет встроенной функции. Просто замените одно, затем другое.
Руах
4
@Bu: Нет, потому что \nв этом контексте будет представлять себя, а не перевод строки. Сейчас у меня нет возможности использовать Bash для тестирования, но вы должны написать что-то вроде $STRING="${STRING/$'\n'/<br />}". (Хотя вы, вероятно, хотите STRING//- заменить все - вместо просто STRING/.)
ruakh
25
Чтобы было ясно, поскольку это немного смутило меня, первая часть должна быть ссылкой на переменную. Вы не можете сделать echo ${my string foo/foo/bar}. Тебе понадобитсяinput="my string foo"; echo ${input/foo/bar}
Henrik N
2
@mgutt: Этот ответ ссылается на соответствующую документацию. Документация не идеальна - например, вместо //непосредственного упоминания , в ней упоминается, что происходит, «если шаблон начинается с /« »(что даже не является точным, поскольку остальная часть этого предложения предполагает, что дополнительное на /самом деле не является частью шаблон) - но я не знаю лучшего источника.
Руах
208
Это можно сделать полностью с помощью манипуляции с 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"
Какой смысл иметь ответ, который дублирует принятый, а не редактировать принятый с глобальной опцией замены? И добавив, что регулярные выражения поддерживаются, пока у него. И объясняя, что случилось с «Плохой заменой». У тебя достаточно очков, @Kevin :)
Дан Даскалеску
6
Похоже, что они оба ответили в одну и ту же минуту: O
Джейми Хатбер,
76
Для Dash все предыдущие посты не работают
POSIX- shсовместимое решение:
result=$(echo "$firstString"| sed "s/Suzi/$secondString/")
Я получил это: $ echo $ (echo $ firstString | sed 's / Suzi / $ secondString / g') Я люблю $ secondString и Marry
Qstnr_La
2
@Qstnr_La использует двойные кавычки для подстановки переменных:result=$(echo $firstString | sed "s/Suzi/$secondString/g")
emc
1
Плюс 1, показывающий, как выводить переменную. Спасибо!
шеф-повар фараона
2
Я исправил одинарные кавычки, а также добавил недостающие кавычки вокруг echoаргумента. Он обманчиво работает без кавычек с простыми строками, но легко разбивается на любую нетривиальную входную строку (неправильный интервал, метасимволы оболочки и т. Д.).
tripleee
В sh (AWS Codebuild / Ubuntu sh) я обнаружил, что в конце мне нужна одна косая черта, а не двойная. Я собираюсь редактировать комментарий, так как комментарии выше также показывают одну косую черту.
Вам на самом деле не нужен Сед для этого; Bash изначально поддерживает такую замену.
ruakh
12
Я думаю, это помечено как "bash", но пришло сюда, потому что нужно что-то простое для другой оболочки. Это хорошая краткая альтернатива тому, что на wiki.ubuntu.com/… выглядело так, как будто мне нужно.
natevw
3
Это прекрасно работает для пепла / тире или любого другого POSIX sh.
Йошуа Вуйц
2
Я получаю ошибку sed: -e выражение # 1, символ 9: неизвестный параметр `s
Nam G VU
1
Первый ответ, который работает с stdin, отлично подходит для конвейерной обработки строк.
Диней
46
Лучше использовать 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с pwdкомандой , чтобы избежать определения новой переменной каждый раз , когда мои собственные $PS1пробеги. Предоставляет ли Bash более общий способ, чем магические переменные, использовать вывод команды для замены строки? Что касается вашего кода, мне пришлось избежать того, ~чтобы Bash не расширил его до $ HOME. Кроме того, что делает #в вашей команде?
Марк Хаферкамп
1
@MarkHaferkamp См. Ссылку «Рекомендуется дальнейшее чтение». Про «побег ~»: обратите внимание, как я цитировал материал. Не забывайте всегда цитировать вещи! И это работает не только для магических переменных: любая переменная способна к подстановкам, получению длины строки и многим другим в bash. Поздравляю с попыткой $PS1быстро: вам также может быть интересно, $PROMPT_COMMANDесли вам удобнее использовать другой язык программирования и вы хотите написать скомпилированное приглашение.
Камило Мартин
Ссылка «дальнейшее чтение» объясняет «#». На Bash 4.3.30 echo "${PWD/#$HOME/~}"не заменяет мой $HOMEна ~. Замена ~на \~или '~'работает. Любая из них работает на Bash 4.2.53 в другом дистрибутиве. Можете ли вы обновить свой пост, чтобы процитировать или избежать ~для лучшей совместимости? Под вопросом «магические переменные» я имел в виду следующее: могу ли я использовать подстановку переменных в Bash, например, на выходе, unameне сохраняя его сначала как переменную? Что касается моего личного $PROMPT_COMMAND, это сложно .
Марк Хаферкамп
@MarkHaferkamp Вау, ты совершенно прав, мой плохой. Обновлю ответ сейчас.
Камило Мартин
1
@MarkHaferkamp Bash и его неясные подводные камни ...: P
Камило Мартин
19
Если завтра вы решите, что не любите замуж, то ее тоже можно заменить:
Поскольку я не могу добавить комментарий. @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}
Пока я пришел к вашему примеру, я понял порядок наоборот. Это помогло прояснить, что происходит
raghav710
5
Чистый 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 loveSuzi 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» между ними.
Ответы:
Чтобы заменить первое вхождение шаблона данной строкой, используйте :
${parameter/pattern/string}
Чтобы заменить все вхождения, используйте :
${parameter//pattern/string}
(Это отражено в в 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:
Это заменит только первое вхождение; чтобы заменить их все, удвойте первую косую черту:
источник
Для Dash все предыдущие посты не работают
POSIX-
sh
совместимое решение:источник
result=$(echo $firstString | sed "s/Suzi/$secondString/g")
echo
аргумента. Он обманчиво работает без кавычек с простыми строками, но легко разбивается на любую нетривиальную входную строку (неправильный интервал, метасимволы оболочки и т. Д.).попробуй это:
источник
Лучше использовать bash, чем
sed
если в строках есть символы RegExp.Он переносим на Windows и работает по крайней мере со старым, как Bash 3.1.
Чтобы показать, что вам не нужно беспокоиться о побеге, давайте обратимся к этому:
В это:
Но только если
/home/name
это в начале. Нам не нужноsed
!Учитывая, что bash дает нам волшебные переменные
$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
, это сложно .Если завтра вы решите, что не любите замуж, то ее тоже можно заменить:
Должно быть 50 способов расстаться с любовником.
источник
Поскольку я не могу добавить комментарий. @ruaka Чтобы сделать пример более читабельным, напишите это так
источник
Чистый POSIX метод оболочки, который в отличии от Roman Kazanovskyi «s
sed
-На ответа не требует никаких внешних инструментов, только собственные родные оболочечных расширения параметров . Обратите внимание, что длинные имена файлов сведены к минимуму, поэтому код лучше помещается в одну строку:Вывод:
Как это работает:
Удалите самый маленький шаблон суффикса.
"${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:
источник
источник