如何遍历文件名带引号的文件并在输出时保留原文件名的引号?
问题原因
你的代码存在两个核心错误:
- 错误使用
ls输出遍历文件:ls是面向人类阅读的命令,输出到管道/变量时会丢弃文件名的特殊字符转义信息,且"$(ls)"会把所有文件名拼接为单个字符串,循环逻辑从根上就错了。 - 未给变量加双引号:
echo $existedFile中变量未包裹双引号,shell会对其做分词、通配符展开,自动丢弃单引号、拆分空格。
你直接执行ls /home/user/source时输出正确,是因为ls检测到输出目标是终端时,会保留带特殊字符文件名的原始显示格式;但当ls的输出被变量捕获时,会自动关闭该格式化逻辑,导致单引号等特殊字符丢失。
正确实现
推荐直接使用shell glob匹配遍历,这是处理特殊文件名最安全的方案,无需调用外部命令:
#!/bin/bash # 直接遍历目标目录下所有文件,glob会保留完整的原始文件名信息 for existedFile in /home/user/source/* do # 仅输出文件名(去掉前缀路径),变量全程用双引号包裹 echo "$(basename -- "$existedFile")" done
如果需要同时匹配目录下的隐藏文件,在循环前加一行shopt -s dotglob开启隐藏文件匹配即可。
内容的提问来源于stack exchange,提问作者Alkaf
相关产品推荐
相关产品推荐

