Maria Ines Parnisari
Maria Ines Parnisari

Reputation: 17506

Sed: syntax error with unexpected "("

I've got file.txt which looks like this:

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

And I'm trying to do two things:

  1. Select the lines that have $id_play as 2nd field.
  2. Replace ; with - on those lines.

My attempt:

#!/usr/bin/perl

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

And I'm getting this error:

sh: 1: Syntax error: "(" unexpected

Why?

Upvotes: 0

Views: 2544

Answers (3)

Ed Morton
Ed Morton

Reputation: 204558

$ 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

Upvotes: 0

drmrgd
drmrgd

Reputation: 733

No need to ever call sed from perl as the perl regex engine already built in and much easier to use. The above answer is perfectly fine. With such a simple dataset, another simple way to do it a little more idiomatically (although maybe a little more obfuscated...then again that sed command was a little complex in itself!) would be:

#!/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

Assuming the file isn't too terribly large, you can just use grep with a regex to grab the lines you are looking for, and then map with a substitution operator to covert those semicolons to hyphens and store the results in a list that you can then print out. I tested it with the DATA block below the code, but instead of reading in from that block, you would probably read in from your file as normal.

edit: Also forgot to mention that in sed, '(' and ')' are treated as literal regular characters and not regex groupings. If you're dead set on sed for such things, use the -r option of sed to have it use those characters in the regex sense.

Upvotes: 0

psxls
psxls

Reputation: 6935

You have to escape the @ characters, add 2 backslashes in some cases (thanks ysth!), add single quotes between sed and make it also filter the lines. So replace with this:

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

PS. What you are trying to do can be achieved in a much more clean way without calling sed and using a split. For example:

#!/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;

Upvotes: 5

Related Questions