我无法弄清楚如何在mac上使用sed将文件CHANGEME
中的CHANGED
更改为myFile.xml
。
<string name="myTag">CHANGEME</string>
我试过了:
sed -i -e "s/\(<string name=\"myTag\">\)\(<\/string>\)/\1CHANGED\2/g" ./myfile.xml
但输出只是沉默。 有什么帮助吗?
答案 0 :(得分:3)
您与<string
和</string>
之间的阻止不匹配。例如,使用[^<]*
来查找找到<
之前的所有内容:
$ sed -e 's/\(<string name="myTag">\)[^<]*\(<\/string>\)/\1CHANGED\2/g' file
<string name="myTag">CHANGED</string>
根据Dipak的建议,如果CHANGED
和<string>
标记中没有文字,您可能希望避免撰写</string>
。如果是这样,您可以说[^<]+
以确保找到至少一个字符:
$ cat a
<string name="myTag">CHANGEME</string>
<string name="myTag"></string>
$ sed -e 's/\(<string name="myTag">\)[^<]\+\(<\/string>\)/\1CHANGED\2/g' a
<string name="myTag">CHANGED</string>
<string name="myTag"></string>
答案 1 :(得分:3)
有两个问题:
您正在使用 GNU Sed语法:在 BSD Sed中,这是OSX上使用的版本,-i
需要和参数,即使它是空字符串(表示应该创建 no 备份),所以必须使用-i ''
(请注意,由于技术原因,-i''
不工作。)
您未匹配元素as fedorqui points out in his helpful answer的内容。
\+
(对于一个或多个匹配)不支持 BSD Sed。\+
替换为符合POSIX的\{1,\}
来轻松解决此问题,但我建议您使用扩展正则表达式代替-E
- 请参阅下方。 除非你必须保持真正的POSIX兼容(在这种情况下你甚至不能使用-i
),我通常建议使用-E
激活对扩展正则表达式的支持的选项:
+
,?
和|
);值得注意的是:\
- 转义字符。例如(
,)
,{
和}
)。一个很好的例子:这里使用-E
修改了您的命令版本:
sed -i '' -E 's/(<string name="myTag">)[^>]+(<\/string>)/\1CHANGED\2/g' ./myfile.xml
请注意,我已经切换到围绕Sed脚本的 单个引号,这也是通常更好的选择:
\
- 逃离"
个实例。答案 2 :(得分:1)
这应该是评论,但由于我没有获得特权,我在这里发帖
Fedorqui建议的代码完全正常并将 CHANGEME 更改为已更改但是,如果标记之间没有任何内容,则会插入已更改
如果要求将空标记保留为空,则可以按如下方式修改代码:
sed 's/\(<string name="myTag">\)[^<].*\(<\/string>\)/\1CHANGED\2/g'
或强>
sed 's/\(<string name="myTag">\)..*\(<\/string>\)/\1CHANGED\2/g' file
在第1种情况下,它会搜索<string name="myTag">
,然后搜索不以<
开头,后跟0次或更多次的内容,并将其替换为已更改。案例2搜索<string name="myTag">
后跟至少一个字符,并将其替换为已更改