我想构造一个匹配两个或多个空格的全局模式,后跟一行文本上的一些文本以进行模式替换。
例如,考虑以下字符串
str="Here is a list of functions Marionette Recutils"
我想替换由两个或多个空格后跟一些文本组成的最后一部分。即在全局模式匹配中" Marionette Recutils"
。
我想要一个匹配两个或多个空格后跟一些文本的模式。想出了以下模式
ptrn="[[:blank:]]+([[:blank:]])+([[:graph:]])"
参数替换的模式是否可以匹配子字符串,从而允许前导字符和尾随字符同时存在?
答案1
对于两个或多个具有全局模式的事物,您可以使用:
{2,}(something)
在 ksh93 中(something)(#c2,)
在zsh -o extendedglob
。something(something)##
在zsh -o extendedglob
。something+(something)
在ksh
或bash -O extglob
(或zsh --emulate ksh
) 中。somethingsomething*(something)
在那些也是如此。
因此在 bash 中:
shopt -s extglob
str="Here is a list of functions Marionette Recutils"
newstr=${str/ +( )*/REPLACEMENT}
或者
newstr=${str/[[:blank:]]+([[:blank:]])*/REPLACEMENT}
在 POSIX sh 中,你还可以这样做:
case str in
(*[[:blank:]][[:blank:]]*) newstr=${str%%[[:blank:]][[:blank:]]*}REPLACEMENT;;
(*) newstr=$str;;
esac
该${str%%pattern}
运算符(最初来自 ksh)删除与 末尾的模式匹配的最长字符串$str
。
答案2
我相当确定这不会处理几种边缘情况,但我成功了......
# echo "Here is a list of functions Marionette Recutils" | sed "s/ .*//"
Here is a list of functions
答案3
简短的:在纯 Bash 中:out=${str/* /}
长的:
str="Here is a list of functions Marionette Recutils"
echo "${str/* /}" # <-- This way
# Out: Marionette Recutils
从man bash
/参数扩展
${parameter/pattern/string}
Pattern substitution. The pattern is expanded to produce a
pattern just as in pathname expansion, Parameter is expanded
and the longest match of pattern against its value is re‐
placed with string.
答案4
关于字符类的令人困惑的事情,例如[:blank:]
是它们代替括号表达式,因此整个事物有两组同心括号:[[:blank:]]
。这也意味着您可以将它们组合起来,例如[[:blank:][:lower:]]
(单个空白或小写字母)或[-_[:alpha:]]
(破折号、下划线或字母),或者对它们进行否定,例如[^[:blank:]]
(任何字符)不是一个空白)。
所以,你可以使用这样的东西:
ptrn="[[:blank:]][[:blank:]]*"
echo "${str%$ptrn}"
要不就:
echo "${str%[[:blank:]][[:blank:]]*}"