用另一个字符替换字符串中的某些字符
Posted
技术标签:
【中文标题】用另一个字符替换字符串中的某些字符【英文标题】:Replacing some characters in a string with another character 【发布时间】:2011-02-21 16:57:11 【问题描述】:我有一个类似AxxBCyyyDEFzzLMN
的字符串,我想用_
替换所有出现的x
、y
和z
。
我怎样才能做到这一点?
我知道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 _
会将每次出现的x
、y
或z
替换为_
,在您的示例中给出A__BC___DEF__LMN
。
echo "$string" | sed -r 's/[xyz]+/_/g'
会将重复出现的x
、y
或z
替换为单个_
,在您的示例中给出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 您不能为此使用tr
。 sed '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
【讨论】:
以上是关于用另一个字符替换字符串中的某些字符的主要内容,如果未能解决你的问题,请参考以下文章