我有一个 makefile 规则,可以构建一个用于分发的 zip/tarbar。在配方中,它做了一些“增值”的事情,比如确保 CR/LF 是正确的,并在打包之前确保执行位是正确的。
该项目文件的自助餐,但这里的要求是:(1)中的所有文件,除了GNUmakefile需要CR/LF,(3)GNUmakefile需要LF而已,(3)中的所有文件,除了GNUmakefile需求a-x。
这是食谱的样子:
.PHONY: convert
convert:
chmod a-x *[^GNUmakefile*] TestData/*.dat TestVectors/*.txt
unix2dos --keepdate --quiet *[^GNUmakefile*] TestData/*.dat TestVectors/*.txt
dos2unix --keepdate --quiet GNUmakefile
Run Code Online (Sandbox Code Playgroud)
我正在使用*并试图避免明确列出自助餐中的所有文件,因为有些文件并不明显,例如 IDE 特定文件。(这*[^<somefile>*]是一个巧妙的技巧;我是从Exclude one pattern from glob match 中得到的)。
问题是我正在匹配TestData和TestVectors执行时chmod a-x,所以我将自己排除在目录之外。
我需要改进一些东西,但我不确定如何。我想使用 shell 的 "*" glob,但排除一个文件并且不匹配目录。
我应该如何进行?
我将通过使用 GNU Makefilter-out和wildcard函数来解决这个问题。您的任务中唯一不能用它们完成的部分是过滤掉目录;这必须通过 shell 来完成。下面的代码未经测试,并假设 (a) 任何文件名中没有空格或 shell 元字符,(b)TestData/*.dat并且TestVectors/*.txt不需要检查目录。
NORM_TOPLEVEL := $(shell for f in $(filter-out GNUMakefile,$(wildcard *)); \
do [ -d "$$f" ] || printf '%s\n' "$$f"; done)
NORM_TESTDIRS := $(wildcard TestData/*.dat) $(wildcard TestVectors/*.txt)
convert:
chmod a-x $(NORM_TOPLEVEL) $(NORM_TESTDIRS)
unix2dos --keepdate --quiet $(NORM_TOPLEVEL) $(NORM_TESTDIRS)
dos2unix --keepdate --quiet GNUmakefile
.PHONY: convert
Run Code Online (Sandbox Code Playgroud)
只有zshglob 可以按类型选择文件,因此,假设 GNU make,您需要类似的东西:
SHELL = zsh
.SHELLFLAGS = -o extendedglob -c
test:
echo ^GNUmakefile(^/)
Run Code Online (Sandbox Code Playgroud)
^GNUmakefile(带有extendedglob)适用于除GNUmakefile. (^/)是一个glob 限定符,用于选择除目录之外的任何类型的文件。另请参阅常规(.)类型的文件(不包括目录和所有其他非常规类型的文件,如 fifos、符号链接、套接字...),这看起来更像您正在寻找的内容。添加glob 限定符 ( ) 以包含隐藏 ( ot ) 文件,例如.D^GNUmakefile(.D)D.gitignore
请注意,扩展为以、、、、 、、、、、、或*[^GNUmakefile*]以外的字符结尾的非隐藏文件名列表。所以它确实会排除(因为它以 结尾),但也会排除or或。GNUmakefil*GNUmakefileefoo.afile.htmlbar.exe
要在不更改 shell 的情况下执行相同的操作,您需要诉诸类似的循环(此处相当于^GNUmakefile(.)):
test:
set -- *; \
for i do \
[ -f "$$i" ] && \
[ ! -L "$$i" ] && \
[ "$$i" != GNUmakefile ] && \
set -- "$$@" "$$i"; \
shift; \
done; \
[ "$$#" -gt 0 ] && echo "$$@"
Run Code Online (Sandbox Code Playgroud)
(替换set -- *为set -- .* *以包含隐藏文件)。
find如果您不能保证以下内容的可用性,最好可能会求助于shell glob zsh:
test:
find . ! -name . -prune ! -name '.*' ! -name GNUmakefile \
-type f -exec echo {} +
find TestData/. ! -name . -prune -name '*.dat' ! -name '.*' \
-type f -exec echo {} +
Run Code Online (Sandbox Code Playgroud)
(删除! -name '.*'以包含隐藏文件)。
| 归档时间: |
|
| 查看次数: |
3543 次 |
| 最近记录: |