Lon*_*ner 5 posix newline makefile escaping sed
注意:这不是“ 是否可以在Makefile中创建多行字符串变量”和其他类似问题的副本。这个问题要求不依赖纯Bash或仅GNU Make的功能的POSIX兼容解决方案。关于堆栈溢出的另一个问题没有此要求。
sed在macOS High Sierra上使用BSD获取以下shell脚本:
printf 'foo\nbaz\n' | sed '/foo/a\
bar
'
Run Code Online (Sandbox Code Playgroud)
输出为:
foo
bar
baz
Run Code Online (Sandbox Code Playgroud)
我怎样才能把同样的东西放进去Makefile?这是我尝试过的方法,但似乎不起作用:
all:
printf 'foo\nbaz\n' | sed '/foo/a\\
bar\
'
Run Code Online (Sandbox Code Playgroud)
这会导致错误:
$ 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
Run Code Online (Sandbox Code Playgroud)
我如何才能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}"
Run Code Online (Sandbox Code Playgroud)
的值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
Run Code Online (Sandbox Code Playgroud)
sed使用make宏简化参数扩展我们可以使用makemacros简化先前解决方案的使用。我们将所有笨拙的部分放入宏中。然后,我们在shell命令中扩展这些宏。这是一个例子:
NX = NX=$$(printf '\nx')
NL = $${NX%x}
all:
$(NX); printf 'foo\nbaz\n' | sed "/foo/a\\$(NL)bar$(NL)"
Run Code Online (Sandbox Code Playgroud)
这是输出:
$ make
NX=$(printf '\nx'); printf 'foo\nbaz\n' | sed "/foo/a\\${NX%x}bar${NX%x}"
foo
bar
baz
Run Code Online (Sandbox Code Playgroud)
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}"
Run Code Online (Sandbox Code Playgroud)
这是输出:
$ make
NX=$(printf '\nx'); NL=${NX%x}; printf 'foo\nbaz\n' | sed "/foo/a\\${NL}bar${NL}"
foo
bar
baz
Run Code Online (Sandbox Code Playgroud)
sed与make宏可以通过make以下宏进一步简化上述解决方案的使用:
NX = NX=$$(printf '\nx'); NL=$${NX%x}
NL = $${NL}
all:
$(NX); printf 'foo\nbaz\n' | sed "/foo/a\\$(NL)bar$(NL)"
Run Code Online (Sandbox Code Playgroud)
这是输出:
$ make
NX=$(printf '\nx'); NL=${NX%x}; printf 'foo\nbaz\n' | sed "/foo/a\\${NL}bar${NL}"
foo
bar
baz
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
144 次 |
| 最近记录: |