如何转义变量字符串中的双斜杠?sed命令执行报错求助
解决sed删除含双斜杠目录行的报错问题
这个问题我之前踩过同款坑!主要是两个原因导致的:sed默认分隔符和变量里的斜杠冲突,加上不同sed版本对-i参数的要求不一样,才会出现expected newer version of sed的错误。
为什么会报错?
你的$row值是//maindir/subdir/testing,里面全是斜杠/,而sed默认用/作为匹配模式的分隔符。当shell展开变量后,你的命令变成了:
sed -i '///maindir/subdir/testing//d' DirtoDelete.txt
这完全不符合sed的语法规则。另外,如果你用的是macOS/BSD系统的sed(不是Linux上的GNU sed),-i参数必须指定备份后缀(比如-i.bak),直接用-i不带后缀会触发版本兼容报错,这就是你看到提示的核心原因。
靠谱的解决方案
方案1:替换sed的分隔符(最省心)
不用/当分隔符,改用其他和变量内容不冲突的字符,比如|或者#。这样不需要转义任何斜杠,直接用变量就行:
# 兼容BSD/macOS sed的写法,会生成备份文件 sed -i.bak "\|$row|d" DirtoDelete.txt # 执行完删掉备份文件 rm DirtoDelete.txt.bak # 如果是Linux的GNU sed,可以直接用(不需要备份后缀) sed -i "\|$row|d" DirtoDelete.txt
这里用双引号是为了让shell展开$row,\|是sed里指定用|作为分隔符的特殊写法,完美避开斜杠的冲突。
方案2:转义变量里的所有斜杠
如果一定要用/作为分隔符,需要把$row里的每个/都转义成\/。可以用shell参数展开或者sed来处理:
# 用bash参数展开直接转义(推荐,更快) row_escaped="${row//\//\\/}" sed -i.bak "/$row_escaped/d" DirtoDelete.txt # 或者用sed命令转义 row_escaped=$(echo "$row" | sed 's/\//\\\//g') sed -i.bak "/$row_escaped/d" DirtoDelete.txt
方案3:用awk替代sed(更直观)
如果觉得sed的语法太绕,awk处理这种带特殊字符的匹配反而更简单,兼容性也更好:
awk -v row="$row" '$0 != row' DirtoDelete.txt > temp.txt && mv temp.txt DirtoDelete.txt
这里用-v参数把shell变量$row传入awk,直接比较整行内容是否等于目标目录,完全不需要处理转义,新手也能看懂。
内容的提问来源于stack exchange,提问作者Jrsys
相关产品推荐
相关产品推荐

