如何让tr命令仅替换参数中指定的精确字符?
问题描述
我尝试转换文件名以移除非法字符,但tr命令并非总是严格按给定参数处理输入。例如执行命令:
$ echo "(hello) - {world}" | tr '()-{}' '_' _______ _ _______
原本仅想替换(、)、-、{和},但ASCII排序中)到{之间的所有字符(包括输入中的字母)也被替换成了_。请问是否有办法让tr仅替换参数中指定的精确字符?
解决方法
调整连字符位置规避范围解析
tr里的连字符-默认是范围符号(比如0-9代表所有数字),把它挪到字符列表的开头或结尾,就会被当作普通字符处理:
$ echo "(hello) - {world}" | tr '(){}-' '_' _hello_ _ _world_
转义连字符
用反斜杠\转义连字符,也能阻止它被解析成范围:
$ echo "(hello) - {world}" | tr '()\-{}' '_' _hello_ _ _world_
用sed精准替换(更直观)
如果嫌tr的规则容易踩坑,直接用sed指定要替换的字符集合,完全不会有范围问题:
$ echo "(hello) - {world}" | sed 's/[(){}_-]/_/g' _hello_ _ _world_
内容的提问来源于stack exchange,提问作者Richard T
相关产品推荐
相关产品推荐

