简体   繁体   English

为什么我的正则表达式会在Makefile中损坏?

[英]Why does my regex break inside a Makefile?

I have a bunch of C source files named sequentially (say f1.c , f2.c , f3.c etc). 我有一堆顺序命名的C源文件(例如f1.cf2.cf3.c等)。

In my Makefile I have a clean: definition which used to look like this: 在我的Makefile中,我有一个clean:定义,该定义以前看起来像这样:

rm -f f1
rm -rf f1.dSYM
rm -f f2
rm -rf f2.dSYM
# etc

So I wanted to replace that with a regex, and this works great if I input it directly into the command line: 因此,我想用正则表达式替换它,如果我直接在命令行中输入它,它将非常有用:

ls | grep -P ^f[0-9]+(|\.dSYM)$ | xargs rm -rf

However, if I then put that command in my clean definition, when I run make clean , I get this: 但是,如果然后将该命令放入我的干净定义中,则在运行make clean ,我得到以下信息:

$ make clean
ls | grep -P ^f[0-9]+(|\.dSYM)| xargs rm -rf
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `ls | grep -P ^ex[0-9]+(|\.dSYM)| xargs rm -rf'
make: *** [clean] Error 2

I guess there are some special characters in my regex that are causing a syntax error... I've tried quoting and escaping stuff but nothing's really helping, does anyone know how I could get this working inside my Makefile? 我猜想我的正则表达式中有一些特殊字符会导致语法错误...我曾尝试引用和转义内容,但实际上并没有什么帮助,有人知道我可以在Makefile中使用它吗?

Yet another solution, using $(wildcard) to find the C sources and pattern substitution to get the derived file names: 还有一种解决方案,使用$(wildcard)查找C源代码并进行模式替换以获取派生的文件名:

SOURCES := $(wildcard f[0-9]*.c)

clean :
    rm -f $(SOURCES:.c=)
    rm -rf $(SOURCES:.c=.dSYM)
ls | grep

is a useless use of ls . ls的无用用法。 http://porkmail.org/era/unix/award.html#ls http://porkmail.org/era/unix/award.html#ls

rm -rf f[0-9] f[0-9]*[0-9] f[0-9]*.dSYM

In clear, use globing . 明确地,使用globing See http://mywiki.wooledge.org/glob . 参见http://mywiki.wooledge.org/glob

Direct solution: quote your regex. 直接解决方案:引用您的正则表达式。 Better solution: globs, brace expansion, and/or find ... -delete . 更好的解决方案:glob,大括号扩展和/或find ... -delete

rm -rf f{1,2}{,.dSYM}
rm -rf f? f?.dSYM
ffind . -regex '.*/f[0-9]' -o -regex '.*/f[0-9].dSYM' -delete

Your command line shell is probably different from the shell make uses. 你的命令行shell可能是不同的外壳make用途。 I guess you use /bin/bash at the command line, but make uses /bin/sh by default. 我猜您在命令行上使用/bin/bash ,但默认情况下使用/bin/sh You can change it by prepending 您可以通过添加前缀来更改它

SHELL=/bin/bash

to the Makefile. 到Makefile。

Adding quotes around vertical bars and parentheses is always safer than use them unquoted. 在竖线和括号周围添加引号始终比使用未引号更安全。 Also note that the dollar sign must be doubled in a Makefile not to be treated as a special character. 另请注意,在Makefile中,美元符号必须加倍,以免被视为特殊字符。

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

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