Maria Ines Parnisari
Maria Ines Parnisari

Reputation: 17496

Sed is not replacing all occurrences of pattern

I've got a the following variable LINES with the format date;album;song;duration;singer;author;genre.

August 2013;MDNA;Falling Free;00:31:40;Madonna;Madonna;Pop
August 2013;MDNA;I don't give a;00:45:40;Madonna;Madonna;Pop
August 2013;MDNA;I'm a sinner;01:00:29;Madonna;Madonna;Pop
August 2013;MDNA;Give Me All Your Luvin';01:15:02;Madonna;Madonna;Pop

I want to output author-song, so I made this script:

echo $LINES | sed s_"^[^;]*;[^;]*;\([^;]*\);[^;]*;[^;]*;\([^;]*\)"_"\2-\1"_g

The desired output is:

Madonna-Falling Free
Madonna-I don't give a
Madonna-I'm a sinner
Madonna-Give Me All Your Luvin'

However, I am getting this:

Madonna-Falling Free;Madonna;Pop August 2013;MDNA;I don't give a;00:45:40;Madonna;Madonna;Pop August 2013;MDNA;I'm a sinner;01:00:29;Madonna;Madonna;Pop August 2013;MDNA;Give Me All Your Luvin';01:15:02;Madonna;Madonna;Pop

Why?

EDIT: I need to use sed.

Upvotes: 0

Views: 269

Answers (4)

Nancy
Nancy

Reputation: 1283

If your format is absolutely permanent, just try below:

echo $line | sed 's#.*;.*;\(.*\);.*;.*;\(.*\);.*#\2-\1#'

Upvotes: 0

Mark Reed
Mark Reed

Reputation: 95252

When I run your sed script on your input, I get this output:

Madonna-Falling Free;Pop
Madonna-I don't give a;Pop
Madonna-I'm a sinner;Pop
Madonna-Give Me All Your Luvin';Pop

which is fine except for the extra ;Pop - you just need to add .*$ to the end of your regex so that the entire line is replaced.

Based on your reported output, I'm guessing your input file is using a different newline convention from what sed expects.

In any case, this is a pretty silly thing to use sed for. Much better with awk, for instance:

awk 'BEGIN {FS=";";OFS="-"} {print $5,$3}'

or, slightly more tersely,

awk -F\; -vOFS=- '{print $5,$3}'

Upvotes: 3

William Pursell
William Pursell

Reputation: 212248

If you want sed to see more than one line of input, you must quote the variable to echo:

echo "$LINES" | sed ...

Note that I'm not even going to try to evaluate the correctness of your sed script; using sed here is a travesty, given that awk is so much better suited to the task.

Upvotes: 1

Edward
Edward

Reputation: 1000

It looks like sed is viewing your entire sample text as a single line. So it is performing the operation requested and then leaving the rest unchanged.
I would look into the newline issue first. How are you populating $LINES?
You should also add to the pattern that seventh field in your input (genre), so that the expression actually does consume all of the text that you want it to. And perhaps anchor the end of the pattern on $ or \b (word boundary) or \s (a spacey character) or \n (newline).

Upvotes: 0

Related Questions