如何在BSD tar的路径替换选项中转义字符?
-s选项中转义字符的问题 我明白你在BSD tar的路径替换选项里遇到的转义困扰——这确实容易踩坑,因为tar的-s选项正则规则和sed有细微差别,而且shell的引号解析也会添乱。让我们一步步拆解问题,找到正确的写法:
先分析你遇到的两个错误
第一个命令的错误:
tar: Invalid regular expression: trailing backslash (\)
你写的-s '/^\.svn\/patches/__patches'有两个问题:- 当用
/作为-s的分隔符时,正则里的/不需要转义——tar会自动把第一个/当作正则起始,第二个/当作正则结束,你加的\/反而会被tar识别为正则末尾有未闭合的反斜杠。 - 缺少最后一个分隔符
/,tar会把替换内容的第一个字符_当作无效的替换标志。
- 当用
第二个命令的错误:
tar: Invalid replacement flag _
单引号里的\\会原封不动传给tar,tar会把\\解析成单个\,所以正则变成^\.svn\/patches,同样因为缺少末尾的/,tar把__patches的_当成了替换标志(tar只接受g、p这类标准标志),所以报错。
正确的两种写法
方法1:换用非/的分隔符(推荐,避免转义)
tar的-s选项允许用任意非空白字符作为分隔符,比如#或@,这样正则里的/不需要转义,写法更清晰:
tar -cf /tmp/z.tar -C /space/myroot -s '#^\.svn/patches#__patches#' src .svn/patches
这里三个#分别标记了正则的开始、替换内容的开始、整个规则的结束,tar能完美识别。
方法2:坚持用/作为分隔符
如果习惯用/,记得不要转义正则里的/,并且在替换内容末尾加上分隔符/:
tar -cf /tmp/z.tar -C /space/myroot -s '/^\.svn/patches/__patches/' src .svn/patches
这样正则部分是^\.svn/patches(匹配以.svn/patches开头的路径),替换部分是__patches,末尾的/告诉tar规则结束,不会把替换内容的字符当成标志。
验证效果
这两种写法都能达到你用sed处理的效果:打包后查看内容,.svn/patches开头的路径会被替换成__patches,完全符合你的需求,不用依赖/^.svn.patches/这种取巧的通配符写法。
内容的提问来源于stack exchange,提问作者user9645

