在shell脚本中替换另一个字符串的子字符串
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在shell脚本中替换另一个字符串的子字符串相关的知识,希望对你有一定的参考价值。
我有“我爱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'
(这在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"。
这可以通过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"
对于Dash,所有以前的帖子都不起作用
POSIX sh
兼容解决方案是:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
如果字符串有RegEx字符,最好使用bash而不是qazxsw poi。
sed
它可以移植到Windows,并且至少与Bash 3.1一样老。
为了表明你不需要担心逃避让我们转过来:
echo ${first_string/Suzi/$second_string}
进入:
/home/name/foo/bar
但只有~/foo/bar
在开始时。我们不需要/home/name
!
鉴于bash为我们提供了魔术变量sed
和$PWD
,我们可以:
$HOME
编辑:感谢Mark Haferkamp在关于引用/逃避echo "${PWD/#$HOME/\~}"
的说明中的评论。*
注意变量~
如何包含斜杠,但这并没有破坏任何东西。
进一步阅读:$HOME
。
如果使用Advanced Bash-Scripting Guide是必须的,一定要sed
。
如果明天你决定不爱结婚,她也可以被替换:
escape every character
离开你的爱人必须有50种方法。
由于我无法添加评论。 @ruaka为了使示例更具可读性,请将其写为这样
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
纯粹的POSIX shell方法,与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}
不同,不需要外部工具,只需要shell自己的原生Roman Kazanovskyi's sed
-based answer。请注意,长文件名最小化,因此代码在一行上更合适:
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,否则为false。 - 如果测试返回true,则使用Remove Smallest Suffix Pattern
Suzi*
“${f%$t*}
”和Remove Smallest Prefix PatternI love
“${f#*$t}
”构建所需的字符串,其间包含第二个字符串and Marry
“$s
”。
以上是关于在shell脚本中替换另一个字符串的子字符串的主要内容,如果未能解决你的问题,请参考以下文章
在Windows批处理中的循环中使用变量替换另一个变量中的子字符串