仅在大括号外替换文件中的字符串

Posted

技术标签:

【中文标题】仅在大括号外替换文件中的字符串【英文标题】:Replace a string in the file outside curly braces only 【发布时间】:2016-10-23 07:09:12 【问题描述】:

我需要替换文件中的一些字符串,但是当字符串在花括号内时,我需要跳过它。类似的东西

sed -i '/[^].*foo.*[^]/ s/foo/bar/g' test.f 

测试文件 test.f 包含如下内容:

bar foo foobarbar foo

这应该只搜索未包含在大括号中的字符串中的 foo。所以结果应该是:

bar bar foobarbar foo

大括号中的所有内容都应该被忽略,即如果字符串以“”开头,则应该忽略它,直到该行中对应的“”。

这不必由 sed 执行。非常感谢。

示例输入:

bar foo foobarbar foo
foo  foo  foo  foo  foo
foo  foo  foo  foo  foo

预期输出:

bar bar foobarbar foo
bar  foo  foo  foo  bar
bar  foo  bar  foo  bar

【问题讨论】:

bar foofoo bar 这样的字符串会发生什么? 嵌套卷曲应该怎么办? foo foo foo foo foofoo foo foo foo foo. 请使用上述 cmets 中询问的信息更新问题。问题本身目前还不清楚.. 基本上大括号内的任何东西都应该被输入,如果里面有另一个大括号也没关系。因此,您的示例的结果将是 bar foo foo foo bar 和 bar foo bar foo bar。 是的 Ed,这就是我的意思,使用单个正则表达式几乎不可能使用标准 shell 实用程序。 【参考方案1】:
$ cat tst.awk

    gsub(/foo/,RS)
    numChars = length()
    rec = ""
    for (charNr=1; charNr<=numChars; charNr++) 
        char = substr($0,charNr,1)
        if ( char == "" )  depth++ 
        if ( char == "" )  depth-- 
        rec = rec ((char == RS) && (depth == 0) ? "bar" : char)
    
    gsub(RS,"foo",rec)
    print rec


$ awk -f tst.awk file
bar bar foobarbar foo
bar  foo  foo  foo  bar
bar  foo  bar  foo  bar

【讨论】:

这是正确的方法,而不是任何基于正则表达式的解决方案 ++ 是吗?此外 gsub() 甚至在这里每行使用两次 每行调用 gsub() 两次不是问题。我们将看看是否有人提出了基于正则表达式的解决方案进行比较。 检查我的.. 我承认我只是好奇。我可能会输掉那场比赛【参考方案2】:

只是为了好玩!

awk 'sub(/foo/,"bar")sub(/ foo$/," bar")sub(/ foo /," bar ")1' file
bar bar foobarbar foo
bar  foo  foo  foo  bar
bar  foo  bar  foo  bar

【讨论】:

以上是关于仅在大括号外替换文件中的字符串的主要内容,如果未能解决你的问题,请参考以下文章

仅在匹配的字符串行中替换文件中的字符

在大括号之间搜索和替换文本(VS代码)

用bash中的另一个字符串替换结束括号

文件夹名称中的最后一个字符无法替换

替换字符串中的括号和方括号

如何使用 Python 或 posix 工具搜索和替换字符串中的匹配括号