Bash 如何删除两个之间的所有内容:';s、 但如果介于{}'之间,则不会;s

Bash 如何删除两个之间的所有内容:';s、 但如果介于{}'之间,则不会;s,bash,perl,awk,sed,Bash,Perl,Awk,Sed,我有这样一个文本文件: This is {an example} of : some of the: text. This is yet {another : example :} of some of the text. :This: is :still :yet another {:example:} of :some text:. This is {an example} of text. This is yet {another : example :} of some of the

我有这样一个文本文件:

This is {an example} of : some of the: text.
This is yet {another : example :} of some of the text.
:This: is :still :yet another {:example:} of :some text:.
This is {an example} of  text.
This is yet {another : example :} of some of the text.
 is yet another {:example:} of .
我需要删除在任何
中找到的任何文本,包括
,但如果它们位于一对
{
}
中,则不需要删除

  • 任何介于
    {
    }
    之间的内容都是安全的,包括
  • 不在
    {
    }
    之间,但在
    之间找到的任何内容都将被删除
  • {
    }
    之外找到的
    都将被删除
输出如下所示:

This is {an example} of : some of the: text.
This is yet {another : example :} of some of the text.
:This: is :still :yet another {:example:} of :some text:.
This is {an example} of  text.
This is yet {another : example :} of some of the text.
 is yet another {:example:} of .
  • 每行只有一组大括号
  • 成对的大括号永远不会跨线拆分
  • 在大括号内或大括号外的行上可以有任意数量的
  • 总是成对出现
如何删除冒号之间的所有内容,包括冒号本身,但不使用大括号保护

到目前为止,我最好的尝试是使用
awk-F{{{print$1}>file1.txt
awk-F{{{print$2}“>file2.txt
等。要将大括号周围的行拆分为不同的行,请在特定文件上运行
sed
以删除部分,但不要在大括号内包含数据的文件上运行,然后将其与
粘贴
组合在一起,但此解决方案过于复杂。

在Perl中:

#!/usr/bin/env perl

while (<>) {
    my @chars = split //;
    foreach my $c (@chars) {
        if ($c eq "{" .. $c eq "}") {
            print "$c";
        } elsif ($c eq ":" ... $c eq ":") {
        }
        else {
            print "$c";
        }
    }
}
!/usr/bin/env perl
而(){
我的@chars=split/;
每个我的$c(@chars){
如果($c eq“{.$c eq“}”){
打印“$c”;
}elsif($c eq:“…$c eq:”){
}
否则{
打印“$c”;
}
}
}
或者更简洁地说:

while (<>) {
    print grep {/\{/ .. /\}/ or not /:/ ... /:/} split //;
}
while(){
打印grep{/\{/./\}/或不/:/…/:/}拆分/;
}
在Perl中:

#!/usr/bin/env perl

while (<>) {
    my @chars = split //;
    foreach my $c (@chars) {
        if ($c eq "{" .. $c eq "}") {
            print "$c";
        } elsif ($c eq ":" ... $c eq ":") {
        }
        else {
            print "$c";
        }
    }
}
!/usr/bin/env perl
而(){
我的@chars=split/;
每个我的$c(@chars){
如果($c eq“{.$c eq“}”){
打印“$c”;
}elsif($c eq:“…$c eq:”){
}
否则{
打印“$c”;
}
}
}
或者更简洁地说:

while (<>) {
    print grep {/\{/ .. /\}/ or not /:/ ... /:/} split //;
}
while(){
打印grep{/\{/./\}/或不/:/…/:/}拆分/;
}

这将按您的要求执行

use strict;
use warnings;

my $data = do {
  local $/;
  <DATA>;
};

my @parts = split m/ ( \{ [^{}]* \} ) /x, $data;

for (@parts) {
  s/ : [^:]* : //gx unless /^\{/;
}

print @parts, "\n";


__DATA__
This is {an example} of : some of the: text.
This is yet {another : example :} of some of the text.
:This: is :still :yet another {:example:} of :some text:.

这就照你说的做

use strict;
use warnings;

my $data = do {
  local $/;
  <DATA>;
};

my @parts = split m/ ( \{ [^{}]* \} ) /x, $data;

for (@parts) {
  s/ : [^:]* : //gx unless /^\{/;
}

print @parts, "\n";


__DATA__
This is {an example} of : some of the: text.
This is yet {another : example :} of some of the text.
:This: is :still :yet another {:example:} of :some text:.

计算大括号和冒号:

perl -ne '
    $b = $c = 0;
    for $char (split //) {
        $b++ if $char eq "{"; 
        $b-- if $char eq "}";
        if ($b > 0) { 
            print $char; 
        }
        else {
            if ($c == 0 and $char eq ":") {
                $c++;
            }
            else {
                print $char if $c == 0;
                $c-- if $c == 1 and $char eq ":";
            }
        }
    }
' <<END
This is {an example} of : some of the: text.
This is yet {another : example :} of some of the text.
:This: is :still :yet another {:example:} of :some text:.
END

计算大括号和冒号:

perl -ne '
    $b = $c = 0;
    for $char (split //) {
        $b++ if $char eq "{"; 
        $b-- if $char eq "}";
        if ($b > 0) { 
            print $char; 
        }
        else {
            if ($c == 0 and $char eq ":") {
                $c++;
            }
            else {
                print $char if $c == 0;
                $c-- if $c == 1 and $char eq ":";
            }
        }
    }
' <<END
This is {an example} of : some of the: text.
This is yet {another : example :} of some of the text.
:This: is :still :yet another {:example:} of :some text:.
END

这很简单,请尝试以下操作:

perl -pe 's/({[^{}]*})|:[^:]*:/$1/g' file

{}中的所有文本都保存在$1中,因此跳过:)

这很简单,请尝试以下操作:

perl -pe 's/({[^{}]*})|:[^:]*:/$1/g' file


{}中的所有文本都保存在$1中,因此被跳过:)

如果你显示真实的数据,总是会有很大帮助。否则答案会变成一系列来回的消息,上面说“好吧,在我拥有的实际数据中”,大括号
{..}
可以嵌套吗?不,它们从来没有嵌套过。只有一个
{/code>和一个
}
每行。谢谢。这很有帮助。如果你显示真实的数据,它总是很有帮助。否则答案会变成一系列来回的消息,说“好吧,在我拥有的实际数据中”大括号
{..}
可以嵌套吗?不,它们从来没有嵌套过。只有一个
{
和一个
}
每行。谢谢。这有助于lotNice+1。你不相信
*?
?@glennjackman:这是一个习惯,我希望是一个好习惯,它可以加速正则表达式模式匹配的执行。其思想是使用
/\{.*}/x
正则表达式引擎必须重复尝试零个或多个字符,直到找到一个后跟右大括号的字符。
。使用
/\{[^}]*\}/x
它只是浏览所有不是右大括号的字符。不,这对许多Perl程序没有任何影响,但它总是很快的。你们把一件简单的事情做得太复杂了,只要你们知道Perl正则表达式替换是如何工作的,这只是一个简单的正则表达式问题。@lihao:我用的是正则表达式。我知道正则表达式交替是如何工作的,尽管它在这里无关紧要。你是什么意思?@Borodin,如果你读了J.Friedl的《掌握正则表达式》一书。这个问题很典型,很好+1。你不相信
*?
?@glennjackman:这是一种习惯,我希望是一种好习惯,它能加速正则表达式模式匹配的执行。其思想是,使用
/\{.*?\}/x
时,正则表达式引擎必须重复尝试零个或多个字符,直到找到一个后跟右大括号的字符
}
。使用
/\{[^}]*\}/x
它只需浏览所有不是右大括号的字符。不,这对许多Perl程序没有任何影响,但它总是很快的。你们把一件简单的事情做得太复杂了,只要你们知道Perl正则表达式替换是如何工作的,这只是一个简单的正则表达式问题。@lihao:我用的是正则表达式。我知道正则表达式交替是如何工作的,尽管它在这里无关紧要。你是什么意思?@Borodin,如果你读了J.Friedl的《掌握正则表达式》一书。这是一个非常典型的问题。-1这是我见过的线条最多的一行。这是个问题吗?它不可读吗?或者这会冒犯你的风格感吗?-1这是我见过的台词最多的一行。这有问题吗?它不可读吗?还是会冒犯你的风格感?