2014-06-18 65 views
0

不确定最好的方式做到这一点,但我可以使用任何bash/awk/sed/perl/...来做这件事吗?格式化字符串从X到Y +

简要说明

我希望能够借此

(Intra TAU success Times(SGW not change) + Intra TAU success Times(SGW change) + Period TAU success Times(SGW not change)+ Period TAU success Times(SGW change))/(Intra TAU request Times(SGW not change) + Intra TAU request Times(SGW change)+ Period TAU request Times(SGW not change)+ Period TAU request Times(SGW change)) x 100% 

,并格式化这个

([Intra TAU success Times(SGW not change)]+[Intra TAU success Times(SGW change)]+[Period TAU success Times(SGW not change)]+[Period TAU success Times(SGW change)])/([Intra TAU request Times(SGW not change)]+[Intra TAU request Times(SGW change)]+[Period TAU request Times(SGW not change)]+[Period TAU request Times(SGW change)])*100 

详细说明

我希望能够借此格式(这将是一个线,仅仅指刚提出这样的清晰度)

(
Intra TAU success Times(SGW not change) + 
Intra TAU success Times(SGW change) + 
Period TAU success Times(SGW not change)+ 
Period TAU success Times(SGW change) 
)/(
Intra TAU request Times(SGW not change) + 
Intra TAU request Times(SGW change)+ 
Period TAU request Times(SGW not change)+ 
Period TAU request Times(SGW change) 
) 
x 100% 

,并产生这种格式:

(
[Intra TAU success Times(SGW not change)]+ 
[Intra TAU success Times(SGW change)]+ 
[Period TAU success Times(SGW not change)]+ 
[Period TAU success Times(SGW change)] 
)/(
[Intra TAU request Times(SGW not change)]+ 
[Intra TAU request Times(SGW change)]+ 
[Period TAU request Times(SGW not change)]+ 
[Period TAU request Times(SGW change)] 
) 
*100 

什么我想要做

1加方括号[]所有柜台

借此串
Intra TAU success Times(SGW not change)
和产生这种
[Intra TAU success Times(SGW not change)]

注意并非所有计数器字符串将在)

2结束与*

3更换x删除%

+1

如果不是所有的字符串以')结尾,那么其他可能性是什么? – hwnd

+0

要考虑的一种策略是将输入按其语义表达,将其解析为结构,然后以新格式输出,而不是将其视为可塑文本。 – DavidO

+0

@hwnd它可能有一些像这样的'Period TAU请求时间'与这个'Period TAU请求时间(SGW更改)'相对应,因此它基本上可以是[az] – HattrickNZ

回答

0

你可以试试这个sed的命令也

$ sed 's/ + /]+[/g;s/+ /]+[/g;s/(I/([I/g;s/))\//)])\//g;s/) x 100%/])*100/g' file 
([Intra TAU success Times(SGW not change)]+[Intra TAU success Times(SGW change)]+[Period TAU success Times(SGW not change)]+[Period TAU success Times(SGW change)])/([Intra TAU request Times(SGW not change)]+[Intra TAU request Times(SGW change)]+[Period TAU request Times(SGW not change)]+[Period TAU request Times(SGW change)])*100 

说明:

s/ + /]+[/g;   # Replace all the ` + ` with `]+[` 
s/+ /]+[/g;   # FRom the above output it again replaces `+ ` with `]+[` 
s/(I/([I/g;   # Again from the above result, it replaces `(I` with `([I` 
s/))\//)])\//g;  # Again from the output of above, it replaces `))/` with `)])/` 
s/) x 100%/])*100/g # Again from the above output, it replaces `) x 100%` with `])*100` 
+0

这个工作。谨慎地给出一个简单的解释? – HattrickNZ

+0

@HattrickNZ解释添加:-) –

0

给出:

STRING="(Intra TAU success Times(SGW not change) + Intra TAU success Times(SGW change) + Period TAU success Times(SGW not change)+ Period TAU success Times(SGW change))/(Intra TAU request Times(SGW not change) + Intra TAU request Times(SGW change)+ Period TAU request Times(SGW not change)+ Period TAU request Times(SGW change)) x 100%"

这适用于你的例子:

echo $STRING | sed 's/Intra/[&/g; s/Period/[&/g; s/change)/&]/g; s/ x/* /g; s/\([0-9]*\)%/\1/g' 

假设:

  • 在的 “内” 或 “周期” 一开始就是 “[” 需要添加
  • 在“变更结束”)是需要添加的“]”
  • “x”在2个空格之间
  • 数字之间没有空格和 “%”

至于sed

  • &表示 “整个匹配”
  • \(...\)捕获组和\1吐出第一捕获组
    \2吐出第二个...等等等等
+0

tks,但输出在' +'sign – HattrickNZ

0

使用perl正则表达式将大量的字母,空格和平衡paranthesis括在大括号中。

use strict; 
use warnings; 

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

$data =~ s{\s*\bx\b\s*}{*}g; 
$data =~ s{%}{}g; 
$data =~ s{\s* ((?:[a-z\s]+|\([a-z\s]+\))+)(?<!\s) \s*}{[$1]}ixg; 

print $data; 

__DATA__ 
(
Intra TAU success Times(SGW not change) + 
Intra TAU success Times(SGW change) + 
Period TAU success Times(SGW not change)+ 
Period TAU success Times(SGW change) 
)/(
Intra TAU request Times(SGW not change) + 
Intra TAU request Times(SGW change)+ 
Period TAU request Times(SGW not change)+ 
Period TAU request Times(SGW change) 
) 
x 100% 

输出:

([Intra TAU success Times(SGW not change)]+[Intra TAU success Times(SGW change)]+[Period TAU success Times(SGW not change)]+[Period TAU success Times(SGW change)])/([Intra TAU request Times(SGW not change)]+[Intra TAU request Times(SGW change)]+[Period TAU request Times(SGW not change)]+[Period TAU request Times(SGW change)])*100 
+0

我究竟该怎么去测试呢?我可以在Windows上使用cygwin中的perl吗?非常感谢 – HattrickNZ

+0

@HattrixNZ你没有可用的Perl? – DavidO

+0

@DavidO我有perg在cygwin或我错过了什么? – HattrickNZ

0

我有一种感觉,其他一些解决方案不够灵活,无法处理您没有告诉我们的一些输入案例(此外,我觉得自己喜欢和Marpa一起玩),所以这里有一个更重的解决方案。

#!perl 
use strict; 
use warnings; 

use Marpa::R2; 
use Data::Dumper; 

my $grammar = Marpa::R2::Scanless::G->new({ 
    source => \(<<'EOGRAMMAR') 
    :default ::= action => ::first 
    lexeme default = latm => 1 

    Expression ::= Division ('x') Percentage 
            action => expression 
    Division ::= Sum ('/') Sum  action => division 
    Sum ::= ('(') Sum (')')     
     | Variable ('+') Sum  action => sum 
     | Variable       

    Percentage ::= Number ('%') 
    Variable ::= VariablePart+  action => variable 
    VariablePart ::= Words   action => [value] 
       | '(' Words ')' action => [values] 

    Words ~ [A-Za-z ]+ 
    Number ~ [\d]+ 
    Whitespace ~ [\s]+ 
    :discard ~ Whitespace 
EOGRAMMAR 
}); 

my $recognizer = Marpa::R2::Scanless::R->new({ 
    grammar => $grammar, 
    semantics_package => 'action', 
}); 

sub action::expression { "$_[1]*$_[2]" } 

sub action::division { "($_[1])/($_[2])" } 

sub action::sum { "$_[1]+$_[2]" } 

sub action::variable { 
    my @parts = @_; 
    shift @parts; 
    @parts = map @$_, @parts; 
    s/^\s+// for @parts; 
    s/\s+$// for @parts; 
    return '[' . join('', @parts) . ']'; 
} 

my $input = do { local $/; <> }; 
$recognizer->read(\$input); 
my $output = $recognizer->value; 
if ($output) { 
    print $$output, "\n"; 
    exit 0; 
} else { 
    print STDERR "Parse failed"; 
    exit 1; 
} 

它使用语法来解析样的表情,你表现的,和语法的行动,而不是建立一个解析树,简单地重构你要求的格式输出。它对于空格和输入中的“变量名称”可能会出现相对的空白,尽管如果表达式中存在我没有捕获到的格式,语法可能不得不被修改。

+0

tks但我如何从Windows上从cygwin获得Marpa?发现这个链接,但不太确定[链接](http://marpa-guide.github.io/chapter1.html) – HattrickNZ

+0

@HattrickNZ'cpan Marpa :: R2' – hobbs

0

这可能为你工作(GNU SED):

sed -r 's/\s*((Intra|Period)[^)]*\))\s*/[\1]/g;s/\s*x\s*/*/;s/%//' file 

环绕字符串与IntraPeriod开始以下)用方括号删除任何前/后的空白。将x替换为*删除任何前/后空格。最后删除%