Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusing Sed One-Liner in Makefile Tutorial

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...

like image 300
Jason R. Mick Avatar asked May 04 '11 22:05

Jason R. Mick


People also ask

What is $@ in MakeFile?

The file name of the target of the rule. If the target is an archive member, then ' $@ ' is the name of the archive file. In a pattern rule that has multiple targets (see Introduction to Pattern Rules), ' $@ ' is the name of whichever target caused the rule's recipe to be run.

How do you use special characters in sed?

Sed uses basic regular expressions. In a BRE, in order to have them treated literally, the characters $. *[\^ need to be quoted by preceding them by a backslash, except inside character sets ( […] ).

How do you use sed command to replace a string in a file?

Find and replace text within a file using sed command Use Stream EDitor (sed) as follows: sed -i 's/old-text/new-text/g' input.txt. The s is the substitute command of sed for find and replace. It tells sed to find all occurrences of 'old-text' and replace with 'new-text' in a file named input.txt.

How do you find a pattern using sed?

If any word appears multiple times in a file then the particular occurrence of the word in each line can be replaced by using `sed` command with the occurrence number. The following `sed` command will replace the second occurrence of the searching pattern in each line of the file, python. txt.


1 Answers

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 > $@
like image 78
CB Bailey Avatar answered Oct 06 '22 08:10

CB Bailey