Mac OS Monterey下grep匹配后sed/perl替换失效问题求助
macOS下grep+perl/sed批量替换内容失效的解决方法
问题根源
- 变量未被Shell解析:原命令中用单引号包裹替换表达式,导致
$oldprojectname和$newprojectname被当作字符串字面量,而非变量。 - 二进制文件处理兼容问题:
.swp这类Vim交换文件是二进制格式,perl默认按文本处理可能出错,sed则会因编码触发illegal byte sequence错误。 - 变量引用不规范:未给变量加双引号,若变量值含空格会导致命令逻辑混乱。
修改后的脚本方案
方案一:使用perl(推荐,更好兼容二进制文件)
newprojectname=NEW oldprojectname=OLD dir=. # 输出匹配的文件列表(可选,用于验证) grep "$oldprojectname" "$dir" -lr --exclude test.sh # 批量替换:双引号解析变量,-b参数处理二进制文件 grep "$oldprojectname" "$dir" -lr --exclude test.sh | xargs perl -i -b -pe"s/$oldprojectname/$newprojectname/g" echo $(sw_vers) cat t1.txt t2.txt
- 关键修改:
- 用双引号包裹替换表达式,让Shell解析变量
- 添加
-b参数,通知perl将文件当作二进制处理,避免破坏.swp这类文件 - 变量引用加双引号,兼容含空格的变量值
方案二:使用sed(解决编码问题)
newprojectname=NEW oldprojectname=OLD dir=. # 输出匹配的文件列表(可选,用于验证) grep "$oldprojectname" "$dir" -lr --exclude test.sh # 设置LC_ALL=C解决编码错误,双引号解析变量,适配macOS sed的-i语法 LC_ALL=C grep "$oldprojectname" "$dir" -lr --exclude test.sh | xargs sed -i '' "s/$oldprojectname/$newprojectname/g" echo $(sw_vers) cat t1.txt t2.txt
- 关键修改:
LC_ALL=C强制使用ASCII编码处理,解决sed的illegal byte sequence错误- 双引号包裹替换表达式,解析变量
- macOS sed的
-i ''表示不生成备份文件(注意-i和空引号之间的空格)
内容的提问来源于stack exchange,提问作者hbaromega
相关产品推荐
相关产品推荐

