Bash中awk提取文件版本行存变量返回多余文件名如何解决
问题原因
- 核心触发点是未加双引号的变量触发了bash通配符展开:你提取到的
VERSION_LINE内容开头是* Version: 1.5.1,其中*是bash的通配符,当你直接用echo $VERSION_LINE(变量无外层双引号)时,bash会先把*替换为当前目录下所有文件名的列表,所以才会输出一堆不相关的文件名,最后才拼接你的目标行内容。 - 第二个语法错误是变量赋值时多写了开头的
$:$VERSION_LINE=$(...)这种写法会让bash先把变量值展开,再当成命令执行,所以匹配到的第一个文件名404.php会被当成命令运行,自然报「command not found」错误。 - 你原有脚本的逻辑本身也存在错误:
awk '/\* Version:/' style.css返回的是匹配行的内容,但你后续sed语法${VERSION_LINE}s/$/-${COMMIT_HASH}/要求${VERSION_LINE}的位置是行号,用行内容当行号不可能匹配到正确的行,哪怕没有通配符问题也无法正常执行。
解决方案
要实现版本号后追加git commit hash的需求,推荐用更简单的单步sed方案,完全规避变量通配符问题:
# 提取前7位commit hash COMMIT_HASH=$(git rev-parse --verify HEAD | head -c 7) # 直接匹配* Version:开头的行,在行尾追加hash sed -i -e '/\* Version:/ s/$/-'"${COMMIT_HASH}"'/' style.css
如果需要保留分步提取的写法,注意所有变量使用时必须包裹双引号,同时修改匹配逻辑为提取行号而非行内容:
# 提取匹配行的行号 VERSION_LINE_NUM=$(awk '/\* Version:/ {print NR}' style.css) COMMIT_HASH=$(git rev-parse --verify HEAD | head -c 7) # 变量加双引号避免异常展开 sed -i -e "${VERSION_LINE_NUM}s/$/-${COMMIT_HASH}/" style.css
验证方法
执行后可以用以下命令确认修改是否正确:
grep '* Version:' style.css
正常会输出类似* Version: 1.5.1-a1b2c3d的结果。
内容的提问来源于stack exchange,提问作者EHerman
相关产品推荐
相关产品推荐

