Shell for循环使用通配符批量复制匹配文件时不生效如何解决?
问题根因
你遇到的通配符被当作字面量处理的报错,核心原因通常是两个:
cut -f1默认按制表符切割字段,如果你的file-names.txt里两列之间是空格而非制表符,会导致读取到的前缀值错误,拼接后的路径没有匹配的文件,bash默认会把未匹配成功的通配符直接作为字面参数传给cp,就触发了找不到文件的报错。- 部分shell环境开启了
failglob选项,会在通配符无匹配时直接返回错误,而非传递通配符本身。
可行解决方案
方案1:用read读取前缀(最稳妥,兼容空格/制表符分隔的文件)
直接用read按空白符分割读取每行的第一列作为前缀,自动适配空格或制表符分隔的配置文件,同时保证通配符正常展开:
while read -r prefix _; do cp raw/"${prefix}"_*.gz ./ done < file-names.txt
说明:_是占位符,用来丢弃每行第二列的序列信息。
方案2:适配分隔符的for循环写法
如果确定要使用for循环,先明确指定cut的分隔符,同时保证通配符不在引号范围内:
# 如果文件是空格分隔 for i in $(cut -d' ' -f1 file-names.txt); do cp raw/${i}_*.gz ./ done # 如果文件是制表符分隔 for i in $(cut -f1 file-names.txt); do cp raw/${i}_*.gz ./ done
额外排查项
如果调整代码后仍报错,先检查file-names.txt是否存在Windows格式的回车符,可执行如下命令转格式后再运行脚本:
dos2unix file-names.txt
内容的提问来源于stack exchange,提问作者Alex Krohn
相关产品推荐
相关产品推荐

