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


279

我有一个像AxxBCyyyDEFzzLMN这样的字符串,我想用_替换所有出现的xyz

我该如何实现?

我知道这echo "$string" | tr 'x' '_' | tr 'y' '_'会行得通,但我想一口气做到这一点,而无需使用管道。


您是否要用一个下划线替换连续的x,y或z的任何序列,还是要用一个下划线替换每个 x,y或z?另外,混合序列怎么样AxyzB?三个下划线还是一个?
大卫·Z

tr '[xyz]'也会替换[]。参数应该只是一个字符列表(尽管范围a-z可以,但在某些实现中,可以使用POSIX字符类[:digit:])。
2006年

Answers:


329
echo "$string" | tr xyz _

将取代的每次出现xyz_,给A__BC___DEF__LMN你的例子。

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

将取代的重复出现xyz与单_,让A_BC_DEF_LMN您的例子。


19
在Mac上,我得到以下信息:sed:非法选项-r用法:sed脚本[-Ealn] [-i扩展名] [文件...] sed [-Ealn] [-i扩展名] [-e脚本]。 .. [-f script_file] ... [file ...]
catanore 2013年

我有一个包含,[]{}()~字符的字符串。我想用逃脱的每个特殊字符替换它,'\'如何通过oneshot完成此操作?
inckka 2014年

2
@halakala Mac附带的sed版本略有不同。看到这个问题:unix.stackexchange.com/questions/13711/… 相反,您可以使用Homebrew软件包管理器安装“ gnu-sed”,然后使用gsed二进制文件:$ brew install gnu-sed然后$ gsed -r 's/[xyz]+/_/g'
John Kary

6
在* BSD(因此是OSX)上,sed -E(基本上)与sed -r许多Linux发行版上的等效,如果使用sed 's/[xyz][xyz]*/_/g',则不需要该选项。当然,这等效于此,tr -s xyz _因此sed这里并不需要。
人间

@inckka您不能使用tr它。 sed 's/[][{}()~,]/\\&/g'但实际上,如果您有后续问题,可以问一个新问题(当然,可以在此处链接以供参考)。顺便说一句,,并且~不是正则表达式元字符(尽管Bash和其他一些shell ~将其扩展到$HOME某些位置;sh但是不是)。
点钟

286

使用Bash参数扩展

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

7
换人不好
阿列克谢2014年

1
@Alexey,我的示例对我有用(bash 4.3.11(1)-发行版)。确保您正在使用bash。其他外壳可能不起作用(尽管有些可以)。
Matthew Flaschen 2014年

谢谢@MatthewFlaschen。这正是我需要用sed替换bash脚本中的绝对路径(用\ /替换/,以便sed接受它)。
Ryan G

1
@RyanG为什么sedbash具有内置替换功能?
MestreLion,2015年

@MestreLion可能出了错,但是我需要用绝对路径替换一堆文件中的标准变量名,为此我使用了sed inplace替换。但是您不能在命令中没有转义的情况下使用“ /”。我当时正以bash的方式进行操作。这不是在bash中操作字符串的最佳方法吗?
Ryan G

111

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

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

一般来说,

将$ substring的第一个匹配项替换为$ replacement:

${string/substring/replacement}

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

${string//substring/replacement}

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


16
请注意,这适用于名为“ string”变量,而不适用于文字字符串。
mattdm

1
最有用的,因为它包含参考。
Os3

最佳和最短的解决方案。
northtree

8
read filename ;
sed -i 's/letter/newletter/g' "$filename" #letter

^根据需要使用任意数量的密码,即可进行自己的BASIC加密


5

这是一个使用shell参数扩展的解决方案,该解决方案用一个替换了多个连续出现的事件_

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

请注意,该模式需要扩展的模式匹配,通过+(pattern)

shopt -s extglob

另外,也可以使用-s(“ squeeze”)选项tr

$ tr -s xyz _ <<< "$var"
A_BC_DEF_LMN
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.