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...
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.
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 ( […] ).
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.
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.
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 > $@
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With