我想包括以下命令(取自这里) 在一个Makefile
。包含该命令的脚本的简单版本Makefile
是:
copy_files:
sed 's/^/\./' ./input_file | \
rev | \
LC_ALL=C sort -u | \
awk 'p == "" || substr($0,1,length(p)) != p { print $0; p = $0 }' | \
rev | \
sed 's/^\.//' > ./output_file
我遇到的问题是,当我使用 执行它时make
,它无法识别该$0
符号:
awk: cmd. line:1: p == "" || substr(,1,length(p)) != p { print ; p = }
awk: cmd. line:1: ^ syntax error
awk: cmd. line:1: p == "" || substr(,1,length(p)) != p { print ; p = }
awk: cmd. line:1: ^ syntax error
我尝试逃避$0
使用\$0
但没有成功。解决办法是什么?
答案1
你走在正确的道路上;转义 Makefile 中的美元符号,你需要使用$$
, 不是\$
:
copy_files:
sed 's/^/\./' ./input_file | \
rev | \
LC_ALL=C sort -u | \
awk 'p == "" || substr($$0,1,length(p)) != p { print $$0; p = $$0 }' | \
rev | \
sed 's/^\.//' > ./output_file
由于您正在使用输入文件构建输出文件,因此您应该明确地告诉 Make:
output_file: input_file
sed 's/^/\./' $< | \
rev | \
LC_ALL=C sort -u | \
awk 'p == "" || substr($$0,1,length(p)) != p { print $$0; p = $$0 }' | \
rev | \
sed 's/^\.//' > $@
output_file
根据这个定义,如果它丢失或input_file
较新,Make 将“重建” 。$<
引用输入(称为先决条件),$@
引用输出(称为目标)。
如果您想要一个copy_files
目标,请将其声明为取决于output_file
:
copy_files: output_file
如果你的 Make 知道虚假目标,也请提及:
.PHONY: copy_files
copy_files: output_file