How can (this specific) awk command be used in make with the result saved to a variable?
I have tried two methods. A) using make's shell function and B) setting an environment variable. Both methods encounter trouble with escaping.
Roughly, the command I am trying to run in a makefile is
awk '{if ( $0 !~ /^#/ ) print $2 }' data.dat | tail -1
I want to store that value to a variable for later use. It's the exclamation mark that is causing the trouble. I have tried various methods of escaping it to no avail.
EDIT: After trying the suggestions below, it appears that the problem is more fundamental than just the exclamation mark. A new smaller test case is something just like
awk '{ print $2 }' data.dat | tail -1
where I'm now assuming the file doesn't have comments. The culprits are now the apostrophes o开发者_运维技巧r that I'm using a UNIX pipe within make.
EDIT 2: Half solution... I was forgetting to use $$ for a $ within make. Hopefully this allows me to post a solution.
EDIT 3: It appears the way parentheses are parsed in make during the definition of make variables, disallows the use commands called by the shell function which used them. Basically this means that gawk one-liners cannot really be used from make if one wants to store the results.
This doesn’t exactly answer your question, but I think you could bypass awk with
grep -v "^#" | cut -f 2 | tail -n 1
You can rewrite your reg-exp to move where the negation takes place, i.e.
awk '{if ( $0 ~ /^[^#]/ ) print $2 }' data.dat | tail -1
# -----^^^^^^^^
which says match any $0 (line) where the first char is NOT the '#' char.
You may be running into other issues because you're using make.
If this doesn't solve your problem, edit your post with your OS version, your $SHELL
value, the version if possible, and gmake
or make
rules. ALSO copy/paste the relevant error messages you're getting.
I hope this helps.
Somehow I miss the scope where within the Makefile you are trying to set a variable. As you already have noticed, you are facing several problems.
When thinking of make(1) and how it handles variables you should think of it as a macro processor (in contrast to expect shell-like behaviour). For example the following Makefile
A = HEHE
B = HOHO
C = $A $B
A = HAHA
default:
echo $C
produces the output "HAHA HOHO" whereas a shell-programmer wold expect "HEHE HOHO". So "later" is a somewhat misleading term with Makefiles.
Of course you can invoke shell commands within rules, but be warned: Each line in a rule is executed within it's own shell process, so even if you set a (Shell-) variable, it's lost with the next command line.
My recomendations:
If you really need to store intermediate values, use temporary files.
If you need to code complex shell commands, place them in a seperate script file
Of course one may use line continuation (\ at end of line) and extended use of escape-quotes to code complex shell constructs within a Makefile and lot of people do so - but this is not what make(1) was designed for - The resulting scripts are horrible to read and searching for errors or misbehaviours is a tedious task.
精彩评论