我有“我爱Suzi和Marry”,我想把“Suzi”改成“Sara”。
firstString="I love Suzi and Marry"secondString="Sara"
期望结果:
firstString="I love Sara and Marry"
试试这个:
sed "s/Suzi/$secondString/g" <<<"$firstString"
要使用给定字符串替换模式的第一出现,请使用${parameter/pattern/string}:
${parameter/pattern/string}
#!/bin/bashfirstString="I love Suzi and Marry"secondString="Sara"echo "${firstString/Suzi/"$secondString"}"# prints 'I love Sara and Marry'
要替换所有出现,请使用${parameter//pattern/string}:
${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参数扩展”中记录。
请注意,POSIX没有指定此功能-它是一个Bash扩展-因此并非所有Unix shell都实现它。有关相关的POSIX留档,请参阅开放组技术标准基础规范,第7期,Shell&U实用程序卷,§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"
对达什来说所有的历史发文都没用
POSIXsh兼容的解决方案是:
sh
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
这将替换每行输入上的第一个出现。添加/g标志来替换所有出现:
/g
result=$(echo "$firstString" | sed "s/Suzi/$secondString/g")
如果字符串有正则表达式字符,使用Bash比sed更好。
sed
echo ${first_string/Suzi/$second_string}
它可移植到Windows,并且至少与Bash 3.1一样古老。
为了表明你不需要太担心逃跑,让我们把这个:
/home/name/foo/bar
进入这个:
~/foo/bar
但前提是/home/name在开头。我们不需要sed!
/home/name
假设Bash为我们提供了魔术变量$PWD和$HOME,我们可以:
$PWD
$HOME
echo "${PWD/#$HOME/\~}"
感谢Mark Haferkamp在评论中对引用/转义~的注释。*
~
注意变量$HOME如何包含斜杠,但这并没有破坏任何东西。
进一步阅读:高级Bash脚本指南。如果必须使用sed,请务必使用逃避每个字符。
如果明天你决定不爱玛丽,她也可以被取代:
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}ormy_string=${full_string/Suzy/Sarah}
纯POSIX shell方法,与Roman Kazanovskyi基于#0的答案不同,它不需要外部工具,只需shell自己的原生参数展开。请注意,长文件名被最小化,因此代码更适合一行:
f="I love Suzi and Marry"s=Sarat=Suzi[ "${f%$t*}" != "$f" ] && f="${f%$t*}$s${f#*$t}"echo "$f"
输出:
I love Sara and Marry
它是如何工作的:
删除最小的后缀模式。如果后缀$t“Suzi*”在$f“I loveSuzi and Marry”中,则"${f%$t*}"返回“I love”。
$t
Suzi*
$f
I love
Suzi and Marry
"${f%$t*}"
但是如果t=Zelda,则"${f%$t*}"不删除任何内容,并返回整个字符串“I love Suzi and Marry”。
t=Zelda
I love Suzi and Marry
这用于测试$t是否在$f中,[ "${f%$t*}" != "$f" ]将评估为true,如果$f字符串包含“Suzi*”,如果不是,则为false。
[ "${f%$t*}" != "$f" ]
如果测试返回true,则使用移除最小后缀模式${f%$t*}"I love"和移除最小前缀模式${f#*$t}"and Marry"构造所需的字符串,中间有第二个字符串$s"Sara"。
${f%$t*}
${f#*$t}
and Marry
$s
Sara
使用AWK:
firstString="I love Suzi and Marry"echo "$firstString" | awk '{gsub("Suzi","Sara"); print}'
echo [string] | sed "s|[original]|[target]|g"
我找到的唯一方法是将字符串存储在文件中,使用ses然后将文件内容存储在var中:
echo "I love Suzy" > tmp.txtsed -i "s/Suzy/Sarah/" tmp.txtset res=`cat tmp.txt`echo $resrm tmp.txt
我不知道我使用的是哪种shell(如果我键入'sh',我唯一找到的是sh-4.2),但所有经典语法都失败了,比如简单的test=${test2}。它失败了2次:在赋值处(必须使用set)和在${}处。
test=${test2}
set
${}
ls *.ext | awk '{print "mv "$1" "$1".newext"}' | sed "s/.ext.newext/.newext/" | parallel {}
用特殊章程替换第一个匹配项的模式:
${参数/模式/字符串}
用特殊章程替换所有出现的模式:
${参数//模式/字符串}
firstString="I love //Suzi// and Marry"secondString="Sara"firstString="${firstString/\/\/Suzi\/\//"$secondString"}"echo $firstString
它将打印:I love Sara and Marry
使用Sed我们可以很容易地做到
Sed-i"s+$value_to_be_replaced+$with_variable1"一些字符"$with_variable2+g"$file_name
我认为这是您的用例最干净的形式:
firstString="${firstString//Suzi/$secondString}"