在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 Pattern I love${f#*$t}”构建所需的字符串,其间包含第二个字符串and Marry$s”。

以上是关于在shell脚本中替换另一个字符串的子字符串的主要内容,如果未能解决你的问题,请参考以下文章

在Windows批处理中的循环中使用变量替换另一个变量中的子字符串

一个字符串中替换多个字符怎么做

用另一个 NSAttributedString 替换 NSAttributedString 的子字符串

在 C# 中将具有给定形式的子字符串替换为另一个

转载:shell脚本之sed使用----替换变量转义字符

查找和替换文件中与另一个文件中的字符串匹配的子字符串