简体   繁体   English

sed命令仅替换匹配的括号内的内容

[英]sed command to replace only what's inside a matching set of parentheses

I have some old code that looks like OldUtility.getList(obj) that has been refactored to be obj.getList() . 我有一些看起来像OldUtility.getList(obj)旧代码,该代码已重构为obj.getList() I'm trying to write a sed command that will correctly refactor my code. 我正在尝试编写sed命令,以正确重构我的代码。 So far, what I have is: 到目前为止,我所拥有的是:

sed -i '' 's/\(OldUtility.getList(\)\(.*\))/\2.getList()/g'

The problem with this is that it greedily grabs the last closing parenthesis on the line. 问题在于,它贪婪地抓住了行中的最后一个右括号。 This means cases like the below do not work: 这意味着以下情况不起作用:
OldUtility.getList(obj).size()
or 要么
someFunc(OldUtility.getList(obj), otherObj.otherFunc())

But I don't want it to be non greedy, because it also needs to handle cases like: 但我不希望它过于贪婪,因为它还需要处理以下情况:
OldUtility.getList(otherObj.toObj()) -> otherObj.toObj().getList() OldUtility.getList(otherObj.toObj()) -> otherObj.toObj().getList()

So the question is how do I get \\2 to be everything inside the parentheses of the OldUtility.getList(...) ? 所以问题是如何使\\2成为OldUtility.getList(...)括号内的所有内容?

If you don't want to capture closing parenthesis, you should use [^)]* instead of .* . 如果您不想捕获右括号,则应该使用[^)]*而不是.*

Tested with this: 经过测试:

echo "OldUtility.getList(otherObj.toObj()) OldUtility.getList(obj).size() someFunc(OldUtility.getList(obj), otherObj.otherFunc())" | sed -E 's/OldUtility.getList.([^)]*)\\)([\\)]*)/\\1\\2.getList()/g'

The command is sed -E 's/OldUtility.getList.([^)]*)\\)([\\)]*)/\\1\\2.getList()/g' . 该命令是sed -E 's/OldUtility.getList.([^)]*)\\)([\\)]*)/\\1\\2.getList()/g'

you're making it more complicated than needed. 您使它变得比所需的更加复杂。

$ echo "OldUtility.getList(obj)" | sed -r 's/(OldUtility.getList\()[^)]*\)/\1)/'

OldUtility.getList()

I guess I misread the question for the argument extract 我想我误解了参数摘录的问题

$ echo "OldUtility.getList(obj)" | sed -r 's/OldUtility(.getList\()([^)]*)\)/\2\1)/'

obj.getList()

it's better to capture the string values from the search pattern to eliminate typos and containing the values in one place. 最好从搜索模式中捕获字符串值,以消除错别字并将这些值包含在一个位置。

It looks like I missed one more. 好像我又错过了一个。 This handles one more level, but gets complicated for sed to handle without lookahead. 这处理了一个更高的级别,但是让sed进行处理而无前瞻性变得复杂。

$ echo "OldUtility.getList(otherObj.toObj())" | 
  sed -r 's/OldUtility(.getList\()([^)]+(\(\))?)/\2\1/'

otherObj.toObj().getList()

Since getList(...) may contain any level of nested parenthesis several times, you can't solve this problem with sed (There's no way to know which closing parenthesis is the good one). 由于getList(...)可能多次包含任何级别的嵌套括号,因此您无法使用sed解决此问题(无法知道哪种闭合括号是好的)。 Here is a pattern you can use with Perl (that has the feature to match nested parenthesis): 这是可以与Perl一起使用的模式(具有匹配嵌套括号的功能):

OldUtility\.getList\(([^()]*+(?:\((?1)\)[^()]*)*+)\)

Details: 细节:

OldUtility\.getList\( # Note that the literal dot and parenthesis must be escaped
(            # open capture group 1
    [^()]*+  # all that is not a parenthesis (zero or more)
    (?:           # open a non capturing group
        \((?1)\)  # recursion with the capture group 1 subpattern
        [^()]*
    )*+           # repeat the non-capturing group (zero or more times)
)
\)

Example: 例:

echo 'OldUtility.getList(otherObj.toObj().toString())' | perl -pe 's/OldUtility\.getList\(([^()]*+(?:\((?1)\)[^()]*)*+)\)/$1.getList()/g'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM