如何在 make 中使用(这个特定的)awk 命令并将结果保存到变量中?

发布于 2024-12-05 17:18:20 字数 581 浏览 0 评论 0原文

我尝试过两种方法。 A) 使用 make 的 shell 函数和 B) 设置环境变量。这两种方法都遇到了转义的麻烦。

粗略地说,我尝试在 makefile 中运行的命令是

awk '{if ( $0 !~ /^#/ ) print $2 }' data.dat | tail -1

我想将该值存储到变量中以供以后使用。造成麻烦的是感叹号。我尝试了各种方法来逃避它,但没有成功。

编辑:尝试以下建议后,问题似乎比感叹号更根本。一个新的较小的测试用例是 就像

 awk '{ print $2 }' data.dat | tail -1

我现在假设文件没有注释一样。现在的罪魁祸首是撇号或者我在 make 中使用了 UNIX 管道。

编辑2:一半的解决方案...我忘记在 make 中使用 $$ 来表示 $ 。希望这能让我发布解决方案。

编辑 3:看起来在 make 变量定义期间在 make 中解析括号的方式,不允许使用它们的 shell 函数调用 use 命令。基本上,这意味着如果想要存储结果,gawk 的单行语句实际上不能在 make 中使用。

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

东风软 2024-12-12 17:18:20

这并不能完全回答你的问题,但我认为你可以绕过 awk

grep -v "^#" | cut -f 2 | tail -n 1

This doesn’t exactly answer your question, but I think you could bypass awk with

grep -v "^#" | cut -f 2 | tail -n 1
青朷 2024-12-12 17:18:20

您可以重写您的正则表达式以移动发生否定的位置,即

awk '{if ( $0 ~ /^[^#]/ ) print $2 }' data.dat | tail -1
       # -----^^^^^^^^

匹配任何 $0 (行),其中第一个字符不是“#”字符。

由于您使用的是 make,因此您可能会遇到其他问题。

如果这不能解决您的问题,请使用您的操作系统版本、$SHELL 值、版本(如果可能)以及 gmakemake规则。还可以复制/粘贴您收到的相关错误消息。

我希望这有帮助。

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.

一个人练习一个人 2024-12-12 17:18:20

不知何故,我错过了您尝试在 Makefile 中设置变量的范围。正如您已经注意到的,您面临着几个问题。

当考虑 make(1) 以及它如何处理变量时,您应该将其视为宏处理器(与预期的类似 shell 的行为相反)。例如,以下 Makefile

A = HEHE
B = HOHO
C = $A $B
A = HAHA

default:
        echo $C

生成输出“HAHA HOHO”,而 shell 程序员则期望输出“HEHE HOHO”。所以“稍后”对于 Makefile 来说是一个有点误导性的术语。

当然,您可以在规则中调用 shell 命令,但请注意:规则中的每一行都在其自己的 shell 进程中执行,因此即使您设置了 (Shell-) 变量,它也会在下一个命令行中丢失。

我的建议:

  • 如果您确实需要存储中间值,请使用临时文件。

  • 如果您需要编写复杂的 shell 命令,请将它们放在单独的脚本文件中

当然,可以使用行继续符(\ 在末尾)行)并扩展使用转义引号在 Makefile 中编码复杂的 shell 结构,很多人都这样做 - 但这不是 make(1) 的设计目的 - 生成的脚本很难阅读和搜索错误或不当行为是一件乏味的事 任务。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文