Answers:
要用给定的字符串替换第一次出现的模式,请使用:${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文档,请参见《 Open Group技术标准基本规范》第7期,Shell&Utilities卷,第2.6.2节“参数扩展”。
\n
在这种情况下它将代表自身,而不是换行符。我现在没有方便的Bash进行测试,但是您应该可以编写类似的东西$STRING="${STRING/$'\n'/<br />}"
。(尽管您可能想要STRING//
-全部替换-而不是仅仅STRING/
。)
echo ${my string foo/foo/bar}
。您需要input="my string foo"; echo ${input/foo/bar}
//
直接提及,而是提及了“如果模式以' /
'” 开头(甚至不准确,因为该句子的其余部分假定多余的/
部分实际上不是该部分的一部分)模式)-但我不知道有任何更好的来源。
这可以完全通过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"
对于Dash,以前的所有帖子均无效
POSIX sh
兼容的解决方案是:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
result=$(echo $firstString | sed "s/Suzi/$secondString/g")
echo
参数周围添加了缺少的引号。它看似不使用简单的字符串引用就可以工作,但是很容易在任何不平凡的输入字符串(不规则间距,shell元字符等)上中断。
尝试这个:
sed "s/Suzi/$secondString/g" <<<"$firstString"
与sed
字符串具有RegExp字符相比,使用bash更好。
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是否提供比魔术变量更通用的方式来使用命令的输出进行字符串替换?至于您的代码,为了避免~
Bash将其扩展到$ HOME ,我不得不进行转义。另外,#
您的命令中的作用是什么?
~
”:注意我如何引用东西。记住总是引用东西!而且这不仅适用于魔术变量:在bash中,任何变量都能够替换,获取字符串长度等。恭喜您尝试$PS1
快速:$PROMPT_COMMAND
如果您对另一种编程语言更熟悉并且想编写一个编译后的提示,那么您可能也会感兴趣。
echo "${PWD/#$HOME/~}"
请勿将替换$HOME
为~
。~
用\~
或代替'~'
。这些都在另一个发行版上针对Bash 4.2.53进行。您能否更新您的帖子以引用或转义以~
获得更好的兼容性?我的“魔术变量”问题是什么意思:我可以在例如Bash的输出上使用Bash的变量替换,uname
而无需先将其保存为变量吗?至于我的个人$PROMPT_COMMAND
,这很复杂。
如果明天您决定不爱结婚,那么她也可以被取代:
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
离开爱人必须有50种方法。
由于我无法添加评论。@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}
纯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
怎么运行的:
删除最小的后缀图案。 如果后缀为“ ”,则"${f%$t*}"
返回“ ”。 I love
$t
Suzi*
$f
I love
Suzi and Marry
但是,如果t=Zelda
,则不"${f%$t*}"
删除任何内容,并返回整个字符串“ I love Suzi and Marry
”。
这用于测试$t
in $f
,如果字符串包含“ ”,则结果[ "${f%$t*}" != "$f" ]
为true,否则为false。$f
Suzi*
如果测试返回真,使用构建体所需的字符串删除最小匹配模式 ${f%$t*}
“ I love
”和删除最小前缀模式 ${f#*$t}
“ and Marry
”,用第二串$s
“ Sara
在...之间”。
我知道这已经很老了,但是由于没有人提到使用awk:
firstString="I love Suzi and Marry"
echo $firstString | awk '{gsub("Suzi","Sara"); print}'
echo [string] | sed "s/[original]/[target]/g"