内容相同换行符不同,为何Bash脚本处理两个文件结果迥异?
问题分析:换行符格式导致Bash脚本匹配失败
核心原因
问题出在字符串匹配时的隐式字符差异:
- 原文件
somefile是CRLF(\r\n)格式,grep提取行时会保留每行末尾的\r字符(回车符)到file2中,但file命令仅标注file2为ASCII text(未提示CRLF)——因为grep输出的换行符是Unix标准的LF(\n),\r被当作行内容的一部分而非换行符组成。 - Bash的
read命令读取file2时,会将\n作为行结束符,但不会自动去除行内的\r,因此$line变量的实际内容是switchport access vlan 119\r。 - 脚本中的判断条件
[ "$line" = "switchport access vlan $vlan" ]是精确匹配,带\r的字符串与脚本中的目标字符串完全不相等,导致条件不成立,无任何输出。
而file1是手动复制粘贴生成,粘贴过程中编辑器自动去除了行内的\r字符(仅保留CRLF换行符),read读取时$line变量内容与目标字符串完全一致,因此匹配成功并输出结果。
验证方法
可以通过以下命令查看file2中的\r字符(\r会显示为^M):
cat -A file2
解决方法
方法1:修改脚本自动去除\r
在read读取行后添加处理,删除变量中的回车符:
#!/bin/bash vlan=119 prev= while read line do # 去除行内的回车符 line=${line//$'\r'/} prev_clean=${prev//$'\r'/} if ([ ! -z "${prev_clean}" ] && [ "$line" = "switchport access vlan $vlan" ]);then echo "${prev_clean}" echo "${line}" fi prev="${line}" done < file2
方法2:转换文件换行符格式
使用dos2unix命令将file2转换为Unix LF格式(自动去除\r):
dos2unix file2
方法3:修改grep命令提前去除\r
在grep输出后添加管道处理,直接删除行内的回车符:
grep "interface\|switchport access vlan" somefile | tr -d '\r' > file2
内容的提问来源于stack exchange,提问作者john smith
相关产品推荐
相关产品推荐

