Bash脚本用变量命名文件时文件名附带\r回车符如何解决
问题说明
编写Bash脚本通过变量值创建文件时,使用如下命令提取内容为文件名变量赋值:
new_name=`sed -n "/:20:/p" $file | awk -F: '{print $3}'`
执行echo $new_name输出显示正常,值为TRS105489299,但调用touch创建文件时,实际生成的文件名为'TRS105489299'$'\r',无法得到预期名称的文件。
通过hexdump命令排查的执行结果如下:
$ sed -n "/:20:/p" ~/1.txt | hexdump.exe -C 00000000 3a 32 30 3a 54 52 53 31 30 35 34 38 39 32 39 39 |:20:TRS105489299| 00000010 0d 0a |..| 00000012 $ sed -n "/:20:/p" ~/1.txt | awk -F: '{print $3}' | hexdump.exe -C 00000000 54 52 53 31 30 35 34 38 39 32 39 39 0d 0a |TRS105489299..| 0000000e
从十六进制结果可确认,提取的变量值末尾携带\r(CR回车符,Windows格式换行符\r\n的组成部分),是文件名异常的根本原因。
解决方法
可根据场景选择以下任意一种方案处理:
- 源头过滤:在awk提取逻辑中直接删除回车符,避免脏字符存入变量
new_name=`sed -n "/:20:/p" $file | awk -F: '{gsub(/\r/, "", $3); print $3}'`
- 变量清洗:赋值完成后通过Bash内置参数扩展移除末尾的回车符,无需依赖外部命令
new_name=${new_name%$'\r'}
- 管道去字符:在提取链路末尾通过
tr命令删除所有回车符,适配多命令拼接的长管道场景
new_name=`sed -n "/:20:/p" $file | awk -F: '{print $3}' | tr -d '\r'`
- 源文件转换:如果待处理的源文件整体为Windows CRLF换行格式,可先使用
dos2unix命令将文件转为Unix LF格式,后续所有文本提取操作都不会再受回车符干扰。
说明:
echo输出时看不到\r是因为回车符会将光标移动到当前行首,后续输出的内容会覆盖原有行内容,肉眼无法识别该字符的存在,不代表变量中不包含该字符。
内容的提问来源于stack exchange,提问作者mhm
相关产品推荐
相关产品推荐

