我是sed中的新手,所以当我在shell中执行以下代码时:
sed -e "/^\s<key>CHANNEL_NAME<\/key>$/{N;s/\(^\s<string>\).+\(<\/string>$\)/\1test\2}" Info.plist > test.plist
Sed给我一个错误:“sed:1:”/ ^ \ sCHANNEL_NAME&lt; \ ...“:替换模式中未转义的换行符”
我的问题:“替代模式中未转义的换行符”究竟意味着什么?
Info.plist文件是这样的:
...
<key>CHANNEL_NAME</key>
<string>App Store</string>
...
我很感激大家都能回答这个问题,谢谢!
谢谢@potong @dogbane @Beta! :)
因为它是Cocoa plist,所以这是我最终的解决方案:
sed '/<key>CHANNEL_NAME<\/key>/{N;s/\(<string>\).*\(<\/string>\)/\1test\2/;}' Info.plist > test.plist
欢迎任何批准该代码的好建议,再次感谢以下所有人!
答案 0 :(得分:4)
这可能适合你(GNU sed):
sed -e '/^\s*<key>CHANNEL_NAME<\/key>$/{n;s/^\(\s*<string>\).\+\(<\/string>\)$/\1test\2/}' Info.plist > test.plist
N.B。您应该在行的开头允许空格(^\s*
)并在比较替换命令的下一行的开头之前打印匹配的行,即使用n
而不是N
。
或者:
sed -e '/^ *<key>CHANNEL_NAME<\/key>$/!b' -e 'n' -e 's/^\( *<string>\)..*\(<\/string>\)$/\1test\2/' Info.plist > test.plist
答案 1 :(得分:1)
既然你说你刚刚学习sed:sed是一个很好的工具,可以在一行上进行简单的替换,但对于其他任何东西只需要使用awk。
这是一个GNU awk解决方案(如果你愿意,你可以把它塞进一行):
$ cat file
...
foo
<key>CHANNEL_NAME</key>
<string>App Store</string>
...
$
$ awk '
found { $0=gensub(/(<string>).*(<\/string>)/,"\\1test\\2",""); found=0 }
/<key>CHANNEL_NAME<\/key>/ { found=1 }
{ print $0 }
' file
...
foo
<key>CHANNEL_NAME</key>
<string>test</string>
...
它与sed解决方案没有太大的不同,但只是尝试修改sed解决方案以执行任何附加解决方案,例如在行输出中添加行号:
$ awk '
found { $0=gensub(/(<string>).*(<\/string>)/,"\\1test\\2",""); found=0 }
/<key>CHANNEL_NAME<\/key>/ { found=1 }
{ print NR, $0 }
' file
1 ...
2 foo
3 <key>CHANNEL_NAME</key>
4 <string>test</string>
5 ...
或将“string”之间的文字替换为CHANNEL_NAME之前的行内容而不是硬编码的“test”:
awk '
found { $0=gensub(/(<string>).*(<\/string>)/,"\\1" rep "\\2",""); found=0 }
/<key>CHANNEL_NAME<\/key>/ { found=1; rep=prev }
{ print $0; prev=$0 }
' file
...
foo
<key>CHANNEL_NAME</key>
<string>foo</string>
...
并且你会发现你需要一个完整的解决方案,可能涉及单个字母和标点符号的噩梦混合,而使用awk这是一个简单的调整来增强你的起始解决方案。