我有“我爱 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 “Shell Parameter Expansion”中。)
请注意,POSIX 并未指定此功能(它是 Bash 扩展),因此并非所有 Unix shell 都实现它。有关相关 POSIX 文档,请参阅The Open Group Technical Standard Base Specifications, Issue 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"
对于 Dash,以前的所有帖子都不起作用
POSIXsh
兼容的解决方案是:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
这将替换每行输入的第一次出现。添加一个/g
标志来替换所有匹配项:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/g")
试试这个:
sed "s/Suzi/$secondString/g" <<<"$firstString"
使用 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
包含斜杠,但这并没有破坏任何东西。
进一步阅读:高级 Bash 脚本指南。
如果 usingsed
是必须的,请务必转义每个字符。
如果明天你决定不爱 Marry,她也可以被替换:
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
离开你的爱人一定有50种方法。
echo [string] | sed "s/[original]/[target]/g"
因为我不能添加评论。@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}
使用AWK:
firstString="I love Suzi and Marry"
echo $firstString | awk '{gsub("Suzi","Sara"); print}'
纯POSIX shell 方法,与Roman Kazanovskyi的sed
基于答案不同,它不需要外部工具,只需要 shell 自己的本机参数扩展。请注意,长文件名已最小化,因此代码更适合一行:
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
”。
这用于测试 if $t
is in $f
with which如果字符串包含 " "[ "${f%$t*}" != "$f" ]
则评估为true ,否则为false。$f
Suzi*
如果测试返回true ,则使用Remove Smallest Suffix Pattern ${f%$t*}
" I love
" 和Remove Smallest Prefix Pattern ${f#*$t}
" "构造所需的字符串and Marry
,第二个字符串$s
" Sara
" 介于两者之间。