2013-10-06 30 views
0

我有file.txt看起來像這樣:桑達:意外的語法錯誤「(」

C00010018;1;17/10/2013;17:00;18;920;113;NONE 
C00010019;1;18/10/2013;17:00;18;920;0;NONE 
C00010020;1;19/10/2013;19:00;18;920;0;NONE 

我試圖做兩件事情:

  1. 選擇具有線$id_play作爲第二字段。
  2. 替換;-在這些線上。

我嘗試:

#!/usr/bin/perl 

$id_play=3; 
$input="./file.txt"; 
$result = `sed [email protected]^\([^;]*\);$id_play;\([^;]*\);\([^;]*\);\([^;]*\);\([^;]*\);\([^;]*\)\[email protected]\1-$id_play-\2-\3-\4-\5-\[email protected] $input`; 

而且我得到這個錯誤:

sh: 1: Syntax error: "(" unexpected 

爲什麼?

+0

您是否必須使用sed? – fugu

+2

從Perl內部運行sed單行程似乎很奇怪。 – TLP

+0

'@ g'需要被轉義,因爲perl會將它作爲一個數組來處理。用'strict strict'打開嚴格的perl – KeepCalmAndCarryOn

回答

5

你必須逃避@字符,在某些情況下添加2個反斜槓(感謝ysth!),在sed之間添加單引號,並使其成爲filter the lines。所以用這個代替:

$result = `sed 's\@^\\([^;]*\\);$id_play;\\([^;]*\\);\\([^;]*\\);\\([^;]*\\);\\([^;]*\\);\\([^;]*\\);\\([^;]*\\)\$\@\\1-$id_play-\\2-\\3-\\4-\\5-\\6-\\7\@g;tx;d;:x' $input`; 

PS。無需撥打sed並使用split,您可以以更簡潔的方式實現您正在嘗試執行的操作。例如:

#!/usr/bin/perl 
use warnings; 
use strict; 

my $id_play=3; 
my $input="file.txt"; 
open (my $IN,'<',$input); 
while (<$IN>) { 
    my @row=split/;/; 
    print join('-',@row) if $row[1]==$id_play; 
} 
close $IN; 
+0

,這對我不起作用;我認爲有些「需要」還需要翻倍 – ysth

+0

如果我要在sed表達式中使用'$'錨點,我是否也必須轉義它? –

+0

ysth我認爲你是對的。沒有錯誤拋出,但正則表達式不會做什麼。我會檢查並更新 – psxls

0

無需調用過,從Perl作爲已經內置Perl的正則表達式引擎和更容易使用的sed。上述答案完全正確。有了這樣一個簡單的數據集,另一種簡單的方法來做到這一點更地道的(雖然也許有點多......混淆然後再是sed命令本身就是一個有點複雜!)是:

#!/usr/bin/perl 
use warnings; 
use strict; 

my $id_play = 3; 
my @result = map { s/;/-/g; $_ } grep { /^\w+;$id_play;/ } <DATA>; 
print @result; 

__DATA__ 
C00010018;1;17/10/2013;17:00;18;920;113;NONE 
C00010019;1;18/10/2013;17:00;18;920;0;NONE 
C00010020;1;19/10/2013;19:00;18;920;0;NONE 
C00010020;3;19/10/2013;19:00;18;920;0;NONE 
C00010019;3;18/10/2013;17:00;18;920;0;NONE 
C00010020;4;19/10/2013;19:00;3;920;0;NONE 

假設該文件不是太大,你可以使用grep和正則表達式來抓取你正在查找的行,然後映射一個替換運算符來將這些分號轉換成連字符,並將結果存儲在一個列表中,然後你可以打印。我使用代碼下面的DATA塊對其進行了測試,但不是從該塊中讀入數據,而是正常讀入文件。

編輯:也忘了提及在sed中,'('和')'被視爲文字常規字符而不是正則表達式分組。如果你在sed上爲這樣的事情死了,使用sed的-r選項讓它在正則表達式中使用這些字符。

0
$ cat file 
C00010018;1;17/10/2013;17:00;18;920;113;NONE 
C00010019;2;18/10/2013;17:00;18;920;0;NONE 
C00010020;3;19/10/2013;19:00;18;920;0;NONE 
$ 
$ id_play=2             
$ 
$ awk -v id="$id_play" -F';' -v OFS='-' '$2==id{$1=$1}1' file 
C00010018;1;17/10/2013;17:00;18;920;113;NONE 
C00010019-2-18/10/2013-17:00-18-920-0-NONE 
C00010020;3;19/10/2013;19:00;18;920;0;NONE