如何删除第一次出现(
和最后一次出现之间的字符串之间的空格)
。假设我有类似的字符串
(remove space ( fromthefile )between space).
我应该得到输出为
(removespace(fromthefile)betweenspace).
答案1
你可以用这种方式做到这一点,
$ echo "(remove space ( fromthefile )between space)." | sed ':l s/\(([^ )]*\)[ ]/\1/;tl'
(removespace(fromthefile)betweenspace).
这只会删除括号之间的空格。
另一个例子,
$ echo "foo bar(remove space ( fromthefile )between space)." | sed ':l s/\(([^ )]*\)[ ]/\1/;tl'
foo bar(removespace(fromthefile)betweenspace).
答案2
我不明白如何仅使用 sed 来完成此操作,因为普通的正则表达式不应该是能够匹配 嵌套括号。幸运的是,像 Perl 这样的东西也支持不那么正则的表达式,就像从在这里回答:
echo "out side (in ( side ( ) ) remove ( spaces ) ) out ( in again )." |
perl -lpe 's/\(([^()]|(?R))*\)/ local $_ = $&; s,\s+,,g; $_ /eg'
out side (in(side())remove(spaces)) out (inagain).
(非)正则表达式的工作原理如下:
\(([^()]+|(?R))*\)
^^| | ||^^ -- literal parenthesis, inside of which:
^ ^ ^| --- group with choice:
^^^^^^ ^^^^ | ---- anything except parenthesis, any number,
| OR this whole pattern again.
^ ----- any number of those two choices
替换部分从 中获取匹配的字符串$&
,在局部变量中修改它,删除所有空白字符,然后返回修改后的值。 (s///
不适用于$&
或$1
直接使用。)
不过,如果您知道一行上只有一组括号,那么会更容易,因此可以从第一个(
到最后一个进行匹配)
。
echo "out (in ( side) here ) out again." |
perl -pe 's/\(.*\)/ $_ = $&; s,\s+,,g; $_ /e'
out (in(side)here) out again.
免责声明:我不知道$_
在内部使用是否s///e
会损坏,但它似乎对我有用。