Skip to content
Advertisement

Using a pipe (or) in sed

From a variable $(JS_SOURCES) containing something like

"    thing.js myapp.mod1.js otherthing.js myapp.mod1.submod.js myapp.othermodule.js   "

make writes a file containing mod1,othermodule.

It works with this code:

./build/modules.txt: $(JS_SOURCES)
    @echo "$(JS_SOURCES)" | sed -r -e 's/sS*myapp.(w+).jsb/ 1/g' -e 's/S*.S*//g' -e 's/^s+//' -e 's/s+$$//' -e 's/bs+b/,/g' > $@

And my question is Why can’t I replace the 3 expressions

-e 's/S*.S*//g' -e 's/^s+//' -e 's/s+$$//'

with one using pipes

-e 's/S*.S*|^s+|s+$$//g'

?

The shorter sed command doesn’t trim the string (the purpose of two of the expressions).

Why doesn’t it work ? How to fix that (without resorting to several expressions of course) ?

OS is Ubuntu 14.10. I’m not interested in using alternative tools but in how to use the pipe in a regular expression with sed called from a makefile.

Advertisement

Answer

Arkanosis is correct: the combination is wrong and it’s wrong in the shell too. It doesn’t have anything to do with make:

echo "    thing.js myapp.mod1.js otherthing.js myapp.mod1.submod.js myapp.othermodule.js   " 
    | sed -r -e 's/sS*myapp.(w+).jsb/ 1/g' 
             -e 's/S*.S*//g' -e 's/^s+//' -e 's/s+$//' -e 's/bs+b/,/g' 
          > /tmp/x.out 
    && echo "|$(cat /tmp/x.out)|"

shows:

|mod1,othermodule|

Now use the all-in-one method:

echo "    thing.js myapp.mod1.js otherthing.js myapp.mod1.submod.js myapp.othermodule.js   " 
    | sed -r -e 's/sS*myapp.(w+).jsb/ 1/g' 
             -e 's/S*.S*|^s+|s+$//g' -e 's/bs+b/,/g' 
          > /tmp/x.out 
    && echo "|$(cat /tmp/x.out)|"

and you get:

| mod1,othermodule|

You must be doing something in your shell command that’s tricking you into thinking it works.

The reason it doesn’t work is that in the original version, each expression in the -e is applied one after the other to the string, so all take effect.

In the new version, with all three conditions condensed into a single expression, it is applied only one time and only one of the three alternatives will be chosen (that’s what the pipe symbol means in a regex).

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement