regex BASH,按照设置模式从文件中删除

wz8daaqr  于 2023-04-22  发布在  其他
关注(0)|答案(5)|浏览(105)

我有一个配置文件,其中包含多个条目。
如何使用bash搜索New并删除它以及与之相关的所有条目?

Test {
   blah..

    site {
        id
    }
    location {
        id
    }
    staff {
        access {
            
        }
    }
}

New {
   blah..

    site {
        id
    }
    location {
        id
    }
    staff {
        access {
            
        }
    }
}

Link {
   blah..

    site {
        id
    }
    location {
        id
    }
    staff {
        access {
            
        }
    }
}

导致

Test {
   blah..

    site {
        id
    }
    location {
        id
    }
    staff {
        access {
            
        }
    }
}

Link {
   blah..

    site {
        id
    }
    location {
        id
    }
    staff {
        access {
            
        }
    }
}

我知道我可以使用grep来找到匹配的结果,但是我如何删除它呢?例如:
grep -m 1 -A25 New test.txt

edit看起来这样可以删除输出并给予正确的结果。

grep -m 1 -A25 New test.txt > test | grep -v -x -f test test.txt,但它留下了一个冗余文件test,原始文件没有更新。
有没有更好的方法来做到这一点,所以没有冗余的文件,并更新原始文件?

dsf9zpds

dsf9zpds1#

命令sed 's/^New/,/^}/d'对我来说很好用。这是我粘贴你的示例时的输出:

Test {
   blah..

    site {
        id
    }
    location {
        id
    }
    staff {
        access {
            
        }
    }
}

Link {
   blah..

    site {
        id
    }
    location {
        id
    }
    staff {
        access {
            
        }
    }
}
c9x0cxw0

c9x0cxw02#

你可以用下面的正则表达式在}\w+[^{]*{之间的空格上进行分割:

/(?<=^\})[^{]*?(?=\w+[^{]*{)/gm

Demo
一旦你有了块,过滤掉New。下面是一个Ruby演示:

ruby -e 'puts $<.read.
            split(/(?<=^\})[^{]*?(?=\w+[^{]*{)/).
            select{|b| b[/\w+/]!="New"}' file

但是你可以用Perl、Python等做同样的事情。
或者,一个Perl:

perl -0777 -pE 's/^New[\s\S]*?\}\s*(?=^\w+\h*\{)//gm' file

正则表达式的Demo

e4yzc0pl

e4yzc0pl3#

使用awk

awk '/^New/{f=1} /^}/&&f==1 {f=0;next} !f' file.txt

输出:

Test {
   blah..

    site {
        id
    }
    location {
        id
    }
    staff {
        access {
            
        }
    }
}

Link {
   blah..

    site {
        id
    }
    location {
        id
    }
    staff {
        access {
            
        }
    }
}
eblbsuwk

eblbsuwk4#

mawk 'BEGIN {  FS = RS "*New {"
              ORS = RS = RS "}" RS } NF < 2'
piah890a

piah890a5#

使用recursive regex的perl解决方案如何:

perl -0777 -pe 's/\bNew\s*(\{(?:[^{}]+|(?1))*})//' test.txt

该模式匹配一个字符串New序列,后跟一组 balanced 的花括号:

  • [^{}]+匹配大括号以外的任何字符。
  • (?1)告诉正则表达式引擎在这个位置嵌入带括号的模式(下面会提到)。
  • (?:[^{}]+|(?1))是上述模式的交替。
  • (\{(?:[^{}]+|(?1))*})由一对花括号括起来,并由(?1)递归引用,以使模式与嵌套的花括号对匹配。

相关问题