gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 15:03:06 26 4
gpt4 key购买 nike

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

Lorem ipsum dolem file1.jar.

  • file1.jar (MD5: 12345678901234567890123456789012)
  • 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}'`/"

最佳答案

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

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)/"

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

这坚持恰好 32 个十六进制数字和行尾的右括号。

其中一条评论问道:

Can sed operate in such a way that the replacement string replaces only the matching groups in the search pattern? For example, given 's/A B \(D\)/C/', it outputs A B C.



如果我理解(澄清)问题,那么您可以通过适当的捕获来做您想做的事情 - 但替换部分必须准确指定您想要的输出(没有像您那样的快捷方式)。因此,例如,您将编写如下内容:
s/\(A B \)\(D\)/\1C/

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

你也可以这样做:
/A B / s/D/C/

这有一个搜索(对于 A B 序列),然后替代查找 D并将其替换为 C .这基本上就是主要答案所暗示的。你也可以这样做:
/\(A B\) D/ s//\1 C/

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

关于sed 仅替换搜索字符串中的匹配部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8280026/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com