从变量的开头和结尾删除与子字符串匹配的模式

32

正如标题所说,我正在寻找一种方法来删除变量开头和结尾处的定义模式。我知道我必须使用#%,但我不知道正确的语法。

在这种情况下,我想删除变量$line中开头的http://以及结尾的/score/,该变量从file.txt读取。


什么样的模式?你能再具体一点吗? - user80168
是的,在这种情况下:http://在开头,/score/在结尾。$line是从file.txt文件中读取的。 - bobylapointe
你要找的是参数扩展,特别是在 Bash 手册的 这一节 结尾附近的 ${parameter#word}${parameter%word} - doubleDown
5个回答

34

嗯,你不能嵌套 ${var%}/${var#} 操作,所以你需要使用临时变量。

就像这里:

var="http://whatever/score/"
temp_var="${var#http://}"
echo "${temp_var%/score/}"

或者,您可以使用正则表达式与(例如)sed:

some_variable="$( echo "$var" | sed -e 's#^http://##; s#/score/$##' )"

我更熟悉正则表达式。这很有趣。我了解一些sed。问题是,如何使用sed生成的输出将其用于另一个命令中。比如说启动一个脚本。./script.sh $variablemodifiedbysed - bobylapointe
2
更新了答案,显示出sed的输出可以存储在变量中以便重复使用。 - user80168
这最终完美地运行了。我花了两个小时来弄清楚这个问题。我相信其他方法也可以解决,但我喜欢使用正则表达式。谢谢! - bobylapointe
为什么要使用sed,当bash已经内置了正则表达式匹配呢? - Charles Duffy
这些叫什么,我如何了解有关在Bash字符串操作中的这些黑客技巧? - axolotl

16
$ var='https://www.google.com/keep/score'
$ var=${var#*//} #removes stuff upto // from begining
$ var=${var%/*} #removes stuff from / all the way to end
$ echo $var
www.google.com/keep

使用更多的“引号”> “双引号”来包含所有包含空格/元字符和每个扩展的文字:"$var""$(command "$var")""${array[@]}""a & b"。对于代码或文字$'s: 'Costs $5 US'ssh host 'echo "$HOSTNAME"',请使用'单引号'。请参见以下链接:http://mywiki.wooledge.org/Quotes,http://mywiki.wooledge.org/Arguments,http://wiki.bash-hackers.org/syntax/words,when-is-double-quoting-necessary - Gilles Quénot

5

您需要分两步完成此操作:

$ string="fooSTUFFfoo"
$ string="${string%foo}"
$ string="${string#foo}"
$ echo "$string"
STUFF

1
在我的情况下,字符串可能以'boo'或'foo'开头,如果它以任何一个开头,我该如何实现“OR”来解析从字符串开头移除“boo”或“foo”? - Nazar

3

通过仅使用内置的bash功能(不运行外部程序,如sed),有一种方法可以一步完成操作--使用BASH_REMATCH

url=http://whatever/score/
re='https?://(.*)/score/'
[[ $url =~ $re ]] && printf '%s\n' "${BASH_REMATCH[1]}"

这将与右侧的正则表达式进行匹配,并将组放入BASH_REMATCH数组中。


话虽如此,更常规的做法是使用两个PE表达式和一个临时变量:

shopt -s extglob
url=http://whatever/score/
val=${url#http?(s)://}; val=${val%/score/}
printf '%s\n' "$val"

在上面的例子中,extglob 选项被用来允许 shell 识别 "extglobs" -- bash 对 glob 语法的扩展(使得 glob-style 模式在一定程度上类似于正则表达式),其中 ?(foo) 的意思是 foo 是可选的。


顺便提一下,在这些示例中我使用的是 printf 而不是 echo,因为 echo 的行为很多都是实现定义的 -- 比如考虑变量内容为 -e-n 的情况。


0

怎么样?

export x='https://www.google.com/keep/score';
var=$(perl -e 'if ( $ENV{x} =~ /(https:\/\/)(.+)(\/score)/ ) { print qq($2);}')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接