使用awk统计含空格文件名的代码行数并累加求和问题
解决Makefile中统计带空格文件名的Python代码行数问题
问题重现
我在Makefile中使用find/wc/awk组合统计项目中所有.py文件的代码行数并计算总和,文件名不含空格时运行正常,但遇到带空格的文件名时,输出会出现文件名截断的问题。
原Makefile代码
qa: @find ./ -type f -name '*.py' -exec \ wc -l "{}" \; | sort -n| awk \ '{printf "%4s %s\n", $$1, $$2}{s+=$$0}END{print s}' @echo ''
正常运行(文件名无空格)
执行make qa后,末尾输出如下:
$ make qa | tail 545 ./vendored/version.py 550 ./types.py 567 ./interchange/from_dataframe.py 702 ./compute.py 716 ./vendored/docscrape.py 1003 ./dataset.py 1267 ./pandas_compat.py 3686 ./parquet/core.py 14347
异常情况(文件名带空格)
先修改文件名,添加空格:
$ mv parquet/core.py "parquet/co re.py" $ ls -la parquet/co*py -rw-rw-r-- 1 luis luis 139281 juil. 19 20:30 'parquet/co re.py'
再次执行make qa,末尾输出出现错误:
(data) luis@spinoza:/tmp/pyarrow$ make qa | tail 545 ./vendored/version.py 550 ./types.py 567 ./interchange/from_dataframe.py 702 ./compute.py 716 ./vendored/docscrape.py 1003 ./dataset.py 1267 ./pandas_compat.py 3686 ./parquet/co <== 文件名被截断! 14347
问题原因
wc -l的输出格式是[行数] [文件名],当文件名包含空格时,awk会将空格后的内容识别为独立字段($3、$4等),导致原代码中$2只能取到空格前的部分,进而出现文件名截断。另外原代码中s+=$$0的写法也不严谨,$$0是整行内容,虽然后续求和结果看似正确,但实际是awk自动忽略了字符串部分,正确的求和应该只累加行数($1)。
解决方法
修改awk的处理逻辑,让它能正确识别带空格的完整文件名,同时修正求和逻辑:
修改后的Makefile
qa: @find ./ -type f -name '*.py' -exec wc -l "{}" \; | sort -n | awk \ '{line_count = $$1; filename = substr($$0, index($$0, $$2)); printf "%4s %s\n", line_count, filename; s += line_count} END {print s}' @echo ''
逻辑说明
- 用
line_count = $$1单独提取行数,避免和文件名字段混淆; - 利用
substr($$0, index($$0, $$2))截取从$$2第一次出现的位置到行尾的内容,这部分就是完整的文件名(不管包含多少空格); - 求和时只累加
line_count(即行数),保证计算准确; - 保持
sort -n对行数进行排序,输出格式和原逻辑一致。
修改后再次运行make qa,带空格的文件名会完整显示,求和结果也正确。
内容的提问来源于stack exchange,提问作者user3313834
相关产品推荐
相关产品推荐

