7

Can anyone explain this sed one-liner in English (the more detail, the better)?

@sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' < $*.d > $@; \
             rm -f $*.d; [ -s $@ ] || rm -f $@

It's part of this tutorial: http://mad-scientist.net/make/autodep.html

I have a non-constant set of source files and want to auto-generate my dependency tree, based on the contents (includes) spelled out in my source files.

I was following the tutorial pretty well up until that...

P.S. I have basic understanding of sed select/replace, but I'm confused by the matching string and all the layers of redirection.... I've also read through the makefile tutorial once so have basic knowledge of standard makefiles...

Jason R. Mick
  • 5,177
  • 4
  • 40
  • 69
  • 2
    When testing this, temporarily remove the rm part or put an echo there to say something like I'd be removing now if I were in production mode. – octopusgrabbus May 04 '11 at 22:19

1 Answers1

12

The sed pattern will be processed by make first, so if the rule that it applies to is trying to build foo.P then $@ will be translated to foo.P and $* to foo. This means that the actual sed command will be something like:

sed 's/\(foo\)\.o[ :]*/\1.o foo.P : /g' < foo.d > foo.P

\(foo\) matches foo exactly and sets the first replacement to what matches (i.e. foo) \. matches a literal dot and [ :]* matches any number of spaces and colons.

As you can see the \1 replacement is a bit redundant as the matched string is fixed. This would have worked just as well.

sed 's/foo\.o[ :]*/foo.o foo.P : /g' < foo.d > foo.P

which could have been made from:

sed 's/$*\.o[ :]*/$*.o $@ : /g' < $*.d > $@
Beta
  • 96,650
  • 16
  • 149
  • 150
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • Great! Thank you so much... I see the first `rm` removes `foo.d`... the second one it looks to me like it checks for `foo.P` and then removes it if it doesn't exist? That doesn't make sense. Can someone give me a brief explanation of how the `[conditional]||command` logic works in shell script? – Jason R. Mick May 05 '11 at 22:39
  • `-s` also checks if the file is non-empty, not just existing, so if the file exists but is empty, it would be deleted. – Keith M Mar 27 '19 at 17:39