使用sed替换字符串的一部分

4
我知道类似的问题已经被问了多次,但我似乎无法让我找到的任何解决方案起作用。我有一个文件中的一行看起来像这样: <package foo="bar" unique-identifier="需要被替换的内容" version="foobar"> 我需要替换上面指示的部分,但我似乎总是改变不想改变的信息。需要替换的文本因文件而异,所以我目前在它的位置使用通配符。以下是我尝试过的方法。 sed 's/unique\-identifier\=\".*\"/unique\-identifier\=\"新文本\"/g' $file >> $newFile sed 's/\bunique\-identifier\=\".*\"\b/unique\-identifier\=\"新文本\"/g' $file >> $newFile sed 's/\<unique\-identifier\=\".*\"\>/unique\-identifier\=\"新文本\"/g' $file >> $newFile sed 's/[[:<:]]unique\-identifier\=\".*\"[[:>:]]/unique\-identifier\=\"新文本\"/g' $file >> $newFile 这些都是我找到的各种解决方案,最后一个是Mac OSX特定的。理想情况下,我想只替换双引号中的内容,但我的正则表达式技能有限。

note: * is greedy! - Karoly Horvath
2
请注意:在处理标记时,请不要使用文本处理工具! - Tom Fenech
使用sed编辑标记会很痛苦(因为当格式改变时,无人希望他们的XML处理工具出现故障)。那看起来像是XML。它是XML吗?如果是XML,那就使用xmlstarlet ed -u '//package/@unique-identifier[.="NEEDS_TO_BE_REPLACED"]' -v 'NEW_TEXT'这样的命令。 - Wintermute
谢谢,@Wintermute。我从未听说过或使用过它,但我刚刚开始使用它,并将在接下来的几天里研究一下。 - I Dabble
1个回答

3

你可以尝试以下方法:

sed 's/unique\-identifier\=\"[^"]*\"/unique\-identifier\=\"NEW_TEXT\"/g' $file >> $newFile
                             ↑

你第一次尝试失败的原因是因为.*是贪婪的,它会尽可能匹配与表达式匹配的内容。在这种情况下,它也匹配了" version="foobar,而表达式的其余部分(\")匹配了最后一个字符。

.*替换为[^"],使该部分匹配除"以外的所有内容。

您还可以删除表达式中的重复和不必要的转义符号,使其更易读,如下所示:

sed 's/\(unique-identifier="\)[^"]*/\1NEW_TEXT/g' $file >> $newFile

谢谢!就像我说的,我的正则表达式水平很弱,所以美化它绝对不是我目前的强项。我还没有尝试过你缩短的解决方案,但长形式非常好用。 - I Dabble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接