开发者

How can (this specific) awk command be used in make with the result saved to a variable?

开发者 https://www.devze.com 2023-04-06 18:16 出处:网络
I have tried two methods. A) using make\'s shell function and B) setting an environment variable. Both methods encounter trouble with escaping.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号