sed仅替换搜索字符串中的匹配部分

sed仅替换搜索字符串中的匹配部分,sed,Sed,我有一个包含以下内容的文件: Lorem ipsum dolem file1.jar file1.jar(MD5:123456789001234567890123456789012) file2.jar(MD5:09876543210987654321098765432109) file3.jar(MD5:24681357902468135790246813579024) 我想替换第一个MD5。此sed命令执行以下任务: sed "s/file1.*MD5\:\(.*\)/file1.jar

我有一个包含以下内容的文件:

Lorem ipsum dolem file1.jar

  • file1.jar(MD5:123456789001234567890123456789012)
  • file2.jar(MD5:09876543210987654321098765432109)
  • file3.jar(MD5:24681357902468135790246813579024)
我想替换第一个MD5。此
sed
命令执行以下任务:

sed "s/file1.*MD5\:\(.*\)/file1.jar \(MD5\: `md5 file1.jar | awk '{print $4}'`\)/"
有没有办法告诉sed仅替换匹配的组,而不替换行的其余部分?例如:

sed "s/file1.*MD5\:\(.*\)/`md5 file1.jar | awk '{print $4}'`/"
这应该可以做到(未经测试):


请注意,这是32个点。

您可以使用搜索指定要匹配的行,然后在替换中使用更简单的正则表达式:

sed "/file1\.jar (MD5: [0-9A-Fa-f]*)/s/(MD5: [^)]*)/(MD5: $(md5 file1.jar | awk '{print $4}'))/"
它使用
$(…)
符号来运行命令。其中最棘手的一点是结尾处,出现序列
)/“
。第一个右括号是
$(…)
符号的结尾;第二个是替换文本中的字符

第一个正则表达式
/file1\.jar(MD5:[0-9A-Fa-f]*)/
相当精确地指定了要匹配的行。然后,知道它是正确的行,替换中的模式可以更简单:搜索部分
/(MD5:[^]*)/
只查找括号中的MD5数据,因为即使许多其他行包含相同的模式,替换也只会应用于所需的一行

我可能倾向于使用:

md5=$(md5 file1.jar | awk '{print $4}')
sed "/file1\.jar (MD5: [0-9A-Fa-f]*)/  s/(MD5: [^)]*)/(MD5: $md5)/"
这在很大程度上澄清了什么是什么(并且不涉及水平滚动条)。您可以在线条匹配模式中更加精确:

md5=$(md5 file1.jar | awk '{print $4}')
sed "/^file1\.jar (MD5: [0-9A-Fa-f]\{32\})\$/  s/(MD5: [^)]*)/(MD5: $md5)/"
它坚持使用32个十六进制数字,并在行尾加上右括号


其中一条评论问道:

sed的操作方式是否可以使替换字符串仅替换搜索模式中的匹配组?例如,给定
的s/ab\(D\)/C/'
,它将输出
ab C

如果我理解(澄清)问题,那么您可以通过适当的捕获来做您想要做的事情-但是替换部件必须准确地指定您想要的输出内容(没有您想要的快捷方式)。因此,例如,您可以编写如下内容:

s/\(A B \)\(D\)/\1C/
(其中捕获
\(D\)
不需要捕获括号,因为替换中未使用捕获的材料,您可以编写以下任一内容:

s/\(A B \)D/\1C/
s/\(A B\) D/\1 C/
你也可以这样做:

/A B / s/D/C/
这是一个搜索(搜索
ab
序列),然后替换项查找
D
,并将其替换为
C
。这基本上就是主要答案所建议的。您可能还可以执行以下操作:

/\(A B\) D/ s//\1 C/
“空搜索”应重复匹配,但替换内容必须完整写出,这实际上与前面的一个命令相同:

s/\(A B\) D/\1 C/

你可以用
\{32\}
写32个点,或者(因为你是在十六进制数字之后)写
[0-9a-fA-F]\{32\}
。此外,使用裸括号作为捕获需要“扩展正则表达式”,这需要在MacOS X和BSD上选择
-E
,以及
-r
(或者
-regex extended
)使用GNU
sed
,这在本机AIX、HP-UX或Solaris版本的
sed
上是不可用的。我似乎永远记不起需要哪些命令(对于子字符串)和需要哪些命令(.+1非常好的解释。而您的命令可能会使搜索更准确(非常感谢),它并没有完全解决我原来的问题。也许我一开始就用词不正确。
sed
是否能够以替换字符串只替换搜索模式中匹配的组的方式进行操作?例如,给定
的s/a B\(D\)/C/“
,它输出
AB C
。那么,我不明白你在问什么。你可以通过适当的捕获来做你想做的事情-但是替换部件必须准确地指定你想要的输出(没有你想要的快捷方式)。啊,好的。这实际上回答了我的问题。:)您介意编辑您的答案以包含您的评论吗?是否有理由使用如此长的正则表达式模式来标识需要更改的行?
/^file1\.jar(MD5:[0-9A-Fa-f]\{32})\$/
/^file1/
@Jaypal类似:您可能会使用一个更短的正则表达式-我引用的正则表达式可以防止大多数事故或错误信息,而更简单的正则表达式可能会被一些意外情况所迷惑。这取决于您对数据中可能发现的内容的了解,这是一个判断调用。Yo几乎可以肯定地使用“<代码> /^文件1\jar / < /COD>”,几乎没有混淆的可能性,但是如果文件有Sh1哈希,替换操作可能失败,等等。我怀疑这是否是一个真正的问题。您可能还需要考虑JAR文件是否具有路径组件。
s/\(A B\) D/\1 C/