用另一个字符替换字符串中的某些字符

Posted

技术标签:

【中文标题】用另一个字符替换字符串中的某些字符【英文标题】:Replacing some characters in a string with another character 【发布时间】:2011-02-21 16:57:11 【问题描述】:

我有一个类似AxxBCyyyDEFzzLMN 的字符串,我想用_ 替换所有出现的xyz

我怎样才能做到这一点?

我知道echo "$string" | tr 'x' '_' | tr 'y' '_' 可以工作,但我想一次性完成,不使用管道。

【问题讨论】:

您是想用 one 下划线替换任意连续的 x、y 或 z 序列,还是要替换 each x, y , 还是带一个下划线的 z?另外,像AxyzB 这样的混合序列呢?三个下划线还是一个? tr '[xyz]' 也将替换 []。参数应该只是一个字符列表(尽管a-z 之类的范围是可以的,在某些实现中,POSIX 字符类例如[:digit:])。 【参考方案1】:

使用Bash Parameter Expansion:

orig="AxxBCyyyDEFzzLMN"
mod=$orig//[xyz]/_

【讨论】:

@Alexey,我的示例对我有用(bash 4.3.11(1)-release)。确保您使用的是bash。其他 shell 可能不起作用(尽管有些会)。 谢谢@MatthewFlaschen。这正是我需要对 bash 脚本中的绝对路径进行 sed 替换(将 / 替换为 \/ 以便 sed 接受它)。 @RyanG 如果 bash 有内置替换,为什么还要使用 sed @MestreLion 这可能是错误的,但我需要用绝对路径替换一堆文件中的标准变量名,为此我使用 sed 就地替换。但是你不能有“/”而不在命令中转义它。我在 bash 中将这些操作串在一起。这不是在 bash 中操作字符串的最佳方式吗? @RyanG sed 接受任何字符作为s 的分隔符。由于您正在处理通常包含许多 / 的路径,因此执行 sed 's#/some/path#/some/other/path#' 可能比执行大量转义更容易(并且更具可读性)【参考方案2】:
echo "$string" | tr xyz _

会将每次出现的xyz 替换为_,在您的示例中给出A__BC___DEF__LMN

echo "$string" | sed -r 's/[xyz]+/_/g'

会将重复出现的xyz 替换为单个_,在您的示例中给出A_BC_DEF_LMN

【讨论】:

在 Mac 上,我得到以下信息: sed: 非法选项 -- r 用法:sed 脚本 [-Ealn] [-i 扩展名] [file ...] sed [-Ealn] [-i扩展名] [-e 脚本] ... [-f 脚本文件] ... [文件 ...] 我有一个包含,[]()~ 字符的字符串。我想用 '\' 转义的每个特殊字符替换它,我怎么能通过 oneshot 完成这个? @halakala Mac 附带的 sed 版本略有不同。看到这个问题:unix.stackexchange.com/questions/13711/… 相反,您可以使用 Homebrew 包管理器安装“gnu-sed”,然后使用 gsed 二进制文件:$ brew install gnu-sed 然后 $ gsed -r 's/[xyz]+/_/g' 在 *BSD(以及 OSX)上,sed -E(基本上)在许多 Linux 发行版上等同于 sed -r,如果您使用 sed 's/[xyz][xyz]*/_/g',则不需要该选项。当然,这相当于tr -s xyz _,所以这里不需要sed @inckka 您不能为此使用trsed 's/[][()~,]/\\&/g' 但实际上,如果您有后续问题,请提出一个新问题(当然,请随时在此处链接以供参考)。顺便说一句,,~ 不是正则表达式元字符(尽管 Bash 和其他一些 shell 在某些位置将 ~ 扩展为 $HOME;但不是 sh)。【参考方案3】:
read filename ;
sed -i 's/letter/newletter/g' "$filename" #letter

^使用尽可能多的这些,您可以制作自己的 BASIC 加密

【讨论】:

【参考方案4】:

您可能会发现此链接很有帮助:

http://tldp.org/LDP/abs/html/string-manipulation.html

一般来说,

用$replacement替换$substring的第一个匹配:

$string/substring/replacement

用 $replacement 替换 $substring 的所有匹配项:

$string//substring/replacement

编辑: 请注意,这适用于名为 $string 的变量。

【讨论】:

请注意,这适用于名为“string”的变量,而不适用于文字字符串。 最有帮助的,因为它包含参考。【参考方案5】:

这是一个带有 shell 参数扩展的解决方案,它用单个 _ 替换多个连续出现:

$ var=AxxBCyyyDEFzzLMN
$ echo "$var//+([xyz])/_"
A_BC_DEF_LMN

请注意,+(<em>pattern</em>) 模式需要扩展模式匹配,打开时使用

shopt -s extglob

或者,使用tr-s(“挤压”)选项:

$ tr -s xyz _ <<< "$var"
A_BC_DEF_LMN

【讨论】:

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

用另一个元素替换字符串中的元素的函数[重复]

用另一个子字符串 C++ 替换子字符串

无法用另一个字符串shell替换文件中的字符串

用另一个表中同一列的值替换列中的字符串值

用另一个字符串替换一个字符串的一部分

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