我有“我爱Suzi和Marry”,我想把“Suzi”改为“Sara”。
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
结果必须如下:
firstString="I love Sara and Marry"
答案 0 :(得分:982)
要使用给定字符串替换模式的第一个出现,请使用${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'
(这在the Bash Reference Manual, §3.5.3 "Shell Parameter Expansion"中有记录。)
请注意,POSIX没有指定此功能 - 它是Bash扩展 - 因此并非所有Unix shell都实现它。有关POSIX文档,请参阅The Open Group Technical Standard Base Specifications, Issue 7, the Shell & Utilities volume, §2.6.2 "Parameter Expansion"。
答案 1 :(得分:158)
这可以完全用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"
答案 2 :(得分:57)
试试这个:
sed "s/Suzi/$secondString/g" <<<"$firstString"
答案 3 :(得分:43)
如果字符串具有RegExp字符,则使用bash比使用sed
更好。
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/\~}"
编辑:感谢Mark Haferkamp在关于引用/转义~
的说明中的评论。*
请注意变量$HOME
如何包含斜杠,但这并没有破坏任何内容。
进一步阅读:Advanced Bash-Scripting Guide。
如果必须使用sed
,请务必escape every character。
答案 4 :(得分:42)
对于Dash,所有以前的帖子都无效
POSIX sh
兼容解决方案是:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
答案 5 :(得分:15)
如果明天你决定不爱结婚,她也可以被替换:
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
离开你的情人必须有50种方法。
答案 6 :(得分:11)
echo [string] | sed "s/[original]/[target]/g"
答案 7 :(得分:2)
由于我无法添加评论。 @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}
答案 8 :(得分:1)
纯 POSIX shell方法,它与Roman Kazanovskyi's sed
-based answer不同,它不需要外部工具,而仅是shell自己的本机parameter expansions。请注意,将长文件名最小化,因此代码更适合一行:
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" ]
中,如果$f
字符串将得出 true 包含“ Suzi*
”,如果没有则包含 false 。
如果测试返回 true ,请使用删除最小后缀模式 ${f%$t*}
“ I love
< / em>”和删除最小前缀模式 ${f#*$t}
“ and Marry
”,并使用 2nd 字符串{{1 }}之间的“ $s
”。
答案 9 :(得分:1)
我知道这已经很老了,但是由于没有人提到使用awk:
vpshufb ymm0, ymm0, ymmword ptr ds:[0x100]