注意:这不是“是否可以在Makefile中创建多行字符串变量”和其他类似问题的副本。这个问题要求不依赖纯Bash或仅GNU Make的功能的POSIX兼容解决方案。关于堆栈溢出的另一个问题没有此要求。
sed
在macOS High Sierra上使用BSD获取以下shell脚本:
printf 'foo\nbaz\n' | sed '/foo/a\
bar
'
输出为:
foo
bar
baz
我怎样才能把同样的东西放进去Makefile
?这是我尝试过的方法,但似乎不起作用:
all:
printf 'foo\nbaz\n' | sed '/foo/a\\
bar\
'
这会导致错误:
$ make
printf 'foo\nbaz\n' | sed '/foo/a\\
/bin/sh: -c: line 0: unexpected EOF while looking for matching `''
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [all] Error 2
我如何才能sed
在Makefile中正确编写上述调用,以便在make
执行all
目标时将尾部斜杠和换行符正确地输入到shell中?
注意:我希望Makefile
兼容POSIX,并且仅使用http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html中的功能。
sed
这是一个将变量<newline>x
(即换行符后跟字符x
)放入变量,然后在sed
命令中使用此变量的解决方案。在使用此变量时,我们使用shell参数扩展来消除x
后缀,以便仅留下换行符。
all:
NX=$$(printf '\nx'); printf 'foo\nbaz\n' | sed "/foo/a\\$${NX%x}bar$${NX%x}"
的价值NX
是<newline>x
,这样${NX%x}
的计算结果为刚<newline>
。这是输出:
$ make
NX=$(printf '\nx'); printf 'foo\nbaz\n' | sed "/foo/a\\${NX%x}bar${NX%x}"
foo
bar
baz
sed
使用make
宏简化参数扩展我们可以使用make
macros简化先前解决方案的使用。我们将所有笨拙的部分放入宏中。然后,在shell命令中扩展这些宏。这是一个例子:
NX = NX=$$(printf '\nx')
NL = $${NX%x}
all:
$(NX); printf 'foo\nbaz\n' | sed "/foo/a\\$(NL)bar$(NL)"
这是输出:
$ make
NX=$(printf '\nx'); printf 'foo\nbaz\n' | sed "/foo/a\\${NX%x}bar${NX%x}"
foo
bar
baz
sed
这是类似线路上的另一种可能的解决方案。代替书写的unwiedly语法${NX%x}
内的sed
命令两次,它通过分配简化${NX%x}
本身到另一个名为shell变量NL
和${NL}
来代替在sed
命令。
all:
NX=$$(printf '\nx'); NL=$${NX%x}; printf 'foo\nbaz\n' | sed "/foo/a\\$${NL}bar$${NL}"
这是输出:
$ make
NX=$(printf '\nx'); NL=${NX%x}; printf 'foo\nbaz\n' | sed "/foo/a\\${NL}bar${NL}"
foo
bar
baz
sed
与make
宏可以通过make
以下宏进一步简化上述解决方案的使用:
NX = NX=$$(printf '\nx'); NL=$${NX%x}
NL = $${NL}
all:
$(NX); printf 'foo\nbaz\n' | sed "/foo/a\\$(NL)bar$(NL)"
这是输出:
$ make
NX=$(printf '\nx'); NL=${NX%x}; printf 'foo\nbaz\n' | sed "/foo/a\\${NL}bar${NL}"
foo
bar
baz
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句