tags:

views:

57

answers:

2

How to replace a few matches in one line using sed?

I have a file.log with text:

sometext1;/somepath1/somepath_abc123/somepath3/file1.a;/somepath1/somepath_abc123/somepath3/file1.o;/somepath1/somepath_abc123/somepath3/file1.cpp;
sometext2;/somepath1/somepath_abc123/somepath3/file2.a;/somepath/somepath_abc123/somepath3/file2.o;/somepath1/somepath_abc123/somepath3/file2.cpp;

And I'm trying to replace somepath1/somepath_abc123/somepath3 in each line.

But unlikely the results is wrong:

sometext1;/mysomepath1/mysomepath2/mysomepath3/file1.cpp;
sometext2;/mysomepath1/mysomepath2/mysomepath3/file2.cpp;

As you can see the sed returns only the last match.

I tried the following code:

#!/bin/sh
FILE="file.log"
OLD="somepath1\/somepath_.*\/somepath3"
NEW="mysomepath1\/mysomepath2\/mysomepath3"
sed  's|'"$OLD"'|'"$NEW"'|g' $FILE > $FILE.out

Whats wrong with the expression?

+1  A: 
#!/bin/bash

awk -F";" '
{
  for(i=1;i<=NF;i++){
    if($i ~ /somepath1.*somepath3/ ){
      sub(/somepath1\/somepath_.*\/somepath3/,"mysomepath1/mysomepath2/mysomepath3",$i)
    }
  }
}
1' OFS=";" file

output

$ ./shell.sh
sometext1;/mysomepath1/mysomepath2/mysomepath3/file1.a;/mysomepath1/mysomepath2/mysomepath3/file1.o;/mysomepath1/mysomepath2/mysomepath3/file1.cpp;
sometext2;/mysomepath1/mysomepath2/mysomepath3/file2.a;/somepath/somepath_abc123/somepath3/file2.o;/mysomepath1/mysomepath2/mysomepath3/file2.cpp;
ghostdog74
Thank you ghostdog74. It works good. But I need to use sed for current task.
pathsag
+2  A: 

Try using [^/] instead of .

#!/bin/sh
FILE="file.log"
OLD="somepath1/somepath_[^/]*/somepath3"
NEW="mysomepath1/mysomepath2/mysomepath3"
sed  "s|$OLD|$NEW|g" $FILE > $FILE.out

Otherwise, replace sed with perl which supports a sed-like invocation:

#!/bin/sh
FILE="file.log"
OLD="somepath1/somepath_.*?/somepath3"
NEW="mysomepath1/mysomepath2/mysomepath3"
perl -pe "s|$OLD|$NEW|g" $FILE > $FILE.out

where .? is the same as . but it is non greedy.

marco
Thank you marco! Replacing [^/] instead of . works perfectly. Now I have expected output.
pathsag