简体   繁体   English

使用fgrep在makefile中输出意外的Perl正则表达式替换

[英]Unexpected perl regex substitution output in makefile using fgrep

Inspired by this rule by prwhite on GitHub prwhite在GitHub上的此规则启发

help:
    @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'`

I'm trying to make a version that replaces target files with spaces. 我正在尝试制作一个用空格替换目标文件的版本。 I want to replace a part of a string with all spaces. 我想用所有空格替换字符串的一部分。 With the file input.txt : 使用文件input.txt

spec: $(ALL_FILES)      ## Runs all specs
myst-spec: $(ALL_FILES) ## Runs just the in-language specs
build: $(SOURCE_FILES)   ## Builds myst into an executable
check: $(ALL_FILES)     ## Runs all crystal specs
clean:                  ## Cleans (deletes) docs and executables
help:                   ## Show this help.

This is the expected output: 这是预期的输出:

spec:                   ## Runs all specs
myst-spec:              ## Runs just the in-language specs
build:                  ## Builds myst into an executable
check:                  ## Runs all crystal specs
clean:                  ## Cleans (deletes) docs and executables
help:                   ## Show this help.

This is the rule i currently have: 这是我目前拥有的规则:

help:
    @fgrep -h "##" input.txt | fgrep -v fgrep | \
      perl -pe 's/(.*):(.*)##(.*)/("$1:" . (" " x length($2)) . " $3")/e'

Note that fgrep is used here, because actually this is supposed to be run on the makefile itself, but i use input.txt here so you don't have to deal with the whole makefile. 注意这里使用了fgrep ,因为实际上这应该在makefile本身上运行,但是我在这里使用input.txt ,因此您不必处理整个makefile。

Unexpectedly, i get this output: 出乎意料的是,我得到以下输出:

:
:
:
:
:
:

What confuses me the most is that if i run the perl script directly on input.txt (like this: cat input.txt | perl -pe 's/(.*):(.*)##(.*)/("$1:" . (" " x length($2)) . " $3")/e' ) – i get the expected output. 最让我困惑的是,如果我直接在input.txt上运行perl脚本(例如: cat input.txt | perl -pe 's/(.*):(.*)##(.*)/("$1:" . (" " x length($2)) . " $3")/e' )–我得到了预期的输出。 What is the reason it gives different output? 它提供不同输出的原因是什么? I realize it (probably) has something to do with fgrep, but I don't see how it would make a difference, so here I am. 我意识到它(可能)与fgrep有关,但我不知道它会产生什么变化,所以我在这里。

If you want to use $ in a recipe you have to escape it from make by doubling it to $$ . 如果要在配方中使用$ ,则必须将其加倍至$$以使其摆脱make的作用。

help:
    @fgrep -h "##" input.txt | fgrep -v fgrep | \
      perl -pe 's/(.*):(.*)##(.*)/("$$1:" . (" " x length($$2)) . " $$3")/e'

The above can be simplified: 上面可以简化:

help:
    @perl -ne'next if !/##/; s/(.*):(.*)##(.*)/ "$$1:".( " " x length($$2) )." $$3" /e; print'

Or (5.10+): 或(5.10+):

help:
    @perl -ne'next if !/##/; s/:\K(.*)(?=##)/ " " x length($$1) /e; print'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM