2014-06-18 100 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替換爲*刪除任何前/後空格。最後刪除%