我需要修改一些Windows路径。
例如,
D:\usr
到
D:\first\usr
所以,我创建了一个变量。
$path = "first\usr"
然后使用以下命令:
sed -i -e 's!\\usr!${path}/g;' test.txt
然而,最终会出现以下情况:
D:\firstSr
如何在sed中转义\u
?
答案 0 :(得分:2)
假设您的path
变量已正确分配(分配中没有空格:path='first\usr'
),请使用一个示例路径逐步修复输入文件test.txt
:
$ cat test.txt
D:\usr
您的原始命令
$ sed 's!\\usr!${path}/g;' test.txt
sed: -e expression #1, char 18: unterminated `s' command
做得不多,因为您已将!
和/
混为分隔符。
修复分隔符:
$ sed 's!\\usr!${path}!g;' test.txt
D:${path}
现在由于单引号,根本没有发生插值。我怀疑这些只是复制粘贴错误,因为你显然有一些输出。
双引号:
$ sed "s!\\usr!${path}!g" test.txt
bash: !\\usr!${path}!g: event not found
现在这与history expansion冲突了。我们可以逃避!
,或使用不同的分隔符。
/
作为分隔符:
$ sed "s/\\usr/${path}/g" test.txt
D:\firstSr
现在我们问题实际上已经开始了。 ${path}
扩展为first\usr
,但\u
在替换字符串中的GNU sed中具有特殊含义:它将以下字符加上大写,因此S
。
即使没有特殊含义,\u
很可能只会扩展到u
,反斜杠就会消失。
转义反斜杠:
$ path='first\\usr'
$ sed "s/\\usr/${path}/g" test.txt
D:\first\usr
这有效。
答案 1 :(得分:0)
根据您使用的shell,您可以使用参数扩展在替换字符串中加倍\
并阻止\u
解释:
path="first\usr"
sed -e "s/\\usr/${path//\\/\\\\}/g" <<< "D:\usr"
使用shell参数扩展替换模式的语法是${parameter/pattern/string}
(一次替换)或${parameter//pattern/string}
(替换所有匹配项)。
此替换不是由POSIX指定的,但在Bash中可用。
如果它不可用,您可能需要通过以下过程过滤$path
:
path=$(echo "$path" | sed 's/[][\\*.%$]/\\&/g')
(N.B。我在此过滤器中也引用了其他sed元字符。)