linux shell 字符串替换字符,关于bash:在shell脚本中替换另一个字符串的一个子字符串...

我有"我爱苏西并结婚",我想把"苏西"改成"萨拉"。

#!/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'

(这记录在bash参考手册和第3.5.3节"shell参数扩展"中。)

请注意,这个特性不是由posix指定的,它是bash扩展,因此并非所有的unix shell都实现它。有关POSIX的相关文档,请参阅OpenGroup技术标准基本规范,第7期,Shell&utilities卷,以及第2.6.2节"参数扩展"。

@Ruakh我该如何写这个带有或条件的语句。如果我想取代苏子或嫁给新的字符串。

@Priyatham51:没有内置的功能。先换一个,然后换另一个。

@谢谢你的回复。我昨天已经这样做了,我只是想和你确认一下,如果有选择的话,这样我就不必写两行代码了。:)

将"n"(换行符)替换为"

"(HTML换行符)是否有效?$STRING="${STRING/

/

}"

@布鲁:不,因为在这种情况下,将代表自己,而不是一个新行。我现在没有现成的bash来测试,但您应该能够编写类似于$STRING="${STRING/$'

'/

}"的东西。(尽管你可能想用STRING//--全部替换--而不是仅仅用STRING/.)。

如果原始字符串包含"/home/user/dir/",我想将"/home/usr"替换为"/home"(获取结果"/home/dir/")?我如何才能摆脱"/"本身的含义?

@Deniomariz:foo=/home/user/dir,后面是echo"${foo/\/home\/user//home}",将打印/home/dir。

要清楚,因为这让我有点困惑,第一部分必须是一个变量引用。你不能做echo ${my string foo/foo/bar}。你需要input="my string foo"; echo ${input/foo/bar}。

@ruakh-mary通常用一个r:d拼写。

@JobJob:谁在乎"通常"的拼写?这首诗写的是《江户记》(12),故事的结尾。

@哦,该死的-他们就这么做了!我的道歉,应该是对手术的评论。要清楚的是-只是有点笑:d

@Deniomariz我有foo ="$(pwd)"和bar="/test/",我现在怎么用echo"${foo/bar/profi/}"

注意:如果替换字符串包含斜杠,只需转义它们。path=/home/me/docs; echo"${path/me\/docs/you\/docs}"

@这是我的用例

这完全可以通过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"

有一个重复接受的答案,而不是用全局替换选项编辑接受的答案,这有什么意义呢?并添加了regexps在执行时受支持。并解释"糟糕的替换"是怎么回事。你有足够的分数,@kevin:)

试试这个:

sed"s/Suzi/$secondString/g" <<

实际上您不需要SED;bash支持这种本地替换。

我猜这是标记为"bash"的,但之所以出现在这里,是因为需要为另一个shell做一些简单的事情。与wiki.ubuntu.com/&hellip;让它看起来像是我需要的东西相比,这是一个很好的简洁的选择。

这对ash/dash或任何其他posix sh都很有用。

我得到错误的sed:-e表达式1,char 9:未知选项到's

@事实上,我发现这对干草堆串很大的情况很有用。另一个选择是我得到了zsh: command too long。

第一个适用于stdin的答案,非常适合于管道字符串。

@这个答案适用于管道。像my_command | sed ... | ...一样

@namgvu或其他任何出现此错误的人,通常意味着搜索或替换节中的一个字符串与分隔符具有相同的字符。例如,通常使用/作为分隔符,但如果字符串包含*nix目录,则会看到该错误,因为它们也具有/字符。

如果字符串有regexp字符,那么使用bash比使用sed要好。

echo ${first_string/Suzi/$second_string}

它可移植到Windows中,至少与bash 3.1一样旧。

为了证明你不需要太担心逃跑,让我们来看看:

/home/name/foo/bar

进入这个:

~/foo/bar

但前提是/home/name是在开始的时候。我们不需要sed!

考虑到bash给了我们神奇的变量$PWD和$HOME,我们可以:

echo"${PWD/#$HOME/\~}"

编辑:感谢Mark Haferkamp对引用/转义~注释的评论。*

注意变量$HOME如何包含斜线,但这并没有破坏任何东西。

进一步阅读:高级bash脚本指南。如果必须使用sed,请确保转义每个字符。

这个答案阻止了我使用sed和pwd命令,以避免每次运行自定义$PS1时定义一个新变量。bash是否提供了比magic变量更通用的方法来使用命令的输出来替换字符串?至于您的代码,我必须避开~,以防止bash将其扩展到$home。还有,你指挥的江户十一〔四〕是做什么的?

@markhaferkamp从"进一步阅读建议"链接中查看。关于"逃离~":注意我是如何引用这些东西的。记住总是引用一些东西!这不仅仅适用于magic变量:任何变量都可以在bash中进行替换、获取字符串长度等等。恭喜您尝试快速使用$PS1:如果您对另一种编程语言更熟悉,并且希望对编译后的提示进行编码,那么您也可能对$PROMPT_COMMAND感兴趣。

"进一步阅读"链接解释了""。在bash 4.3.30上,echo"${PWD/#$HOME/~}"没有用~替换我的$HOME。用\~或'~'工程代替~。在另一个发行版上的bash 4.2.53上的任何这些工作。为了更好的兼容性,您能更新您的文章来引用或退出~吗?我的"魔法变量"问题的意思是:我可以在不首先将其保存为变量的情况下,在uname的输出上使用bash的变量替换吗?至于我的个人$PROMPT_COMMAND,这很复杂。

@马克哈弗坎普,哇,你完全是对的,我的错。将立即更新答案。

我好像错了……实际上,在chakra linux和opensuse之间重新启动(而不是chrooting)表明,${PWD/#$HOME/~}在suse上的bash 4.2.53中工作,${PWD/#$HOME/\~}在chakra上的bash 4.3.30中工作,但反之则不一样。在两个发行版上都有效的解决方法是用$(echo '~')替换~,就像在冗长的${PWD/#$HOME/$(echo '~')}中一样。编辑:我刚意识到$'~'可能更好。我正在测试它。

请忽略我以前评论中的编辑。$'~'在echo命令中效果很好,但是当我试图用它在$ps1中得到一个文本~时,只引起了我的沮丧。$(echo '~')似乎是最好的解决方法。

@马克哈费尔坎普巴什及其模糊的陷阱…P

对于dash,所有以前的帖子都不起作用

posix sh兼容的解决方案是:

result=$(echo"$firstString" | sed"s/Suzi/$secondString/")

我收到这个:$echo$(echo$firststring sed's/suzi/$secondstring/g),我爱$secondstring并结婚。

@qstnr_la使用双引号替换变量:result=$(echo $firstString | sed"s/Suzi/$secondString/g")。

加1表示如何输出到变量。谢谢!

我修复了单引号,并在echo参数周围添加了缺失的引号。它可以在不引用简单字符串的情况下进行欺骗,但很容易在任何重要的输入字符串(不规则间距、shell元字符等)上中断。

在sh(aws codebuild/ubuntu sh)中,我发现在末尾需要一个斜线,而不是一个双斜线。我将编辑注释,因为上面的注释也显示一个斜线。

如果明天你决定不爱结婚,她也可以被取代:

today=$(

tomorrow="${today//Suzi/Sara}"

echo"${tomorrow//Marry/Jesica}"> /tmp/lovers.txt

必须有50种方法离开你的爱人。

是的,你是对的!

纯posix shell方法与基于Roman Kazanovskyi的sed的答案不同,它不需要外部工具,只需要shell自己的本地参数扩展。请注意,长文件名被最小化,因此代码更适合一行:

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

它是如何工作的:

删除最小后缀模式。如果后缀$t中的"Suzi*在$f中,I loveSuzi and Marry中,"${f%$t*}"返回"EDOCX1〔13]。

但如果t=Zelda,则"${f%$t*}"不删除任何内容,并返回整个字符串"I love Suzi and Marry"。

用于测试$t是否在$f中,["${f%$t*}" !="$f" ]是否在$f中,如果$f字符串包含"Suzi*则评估为真,否则评估为假。

如果测试返回true,则使用删除最小后缀模式${f%$t*}"I love"构造所需字符串,并删除最小前缀模式${f#*$t}"and Marry",其中第二个字符串$s"Sara"。

因为我不能添加评论。@Ruaka为了使示例更易读,请这样写

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}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值