6 sed
我有一个包含以下内容的文件:
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}'`\)/"
Run Code Online (Sandbox Code Playgroud)
有没有办法告诉sed只更换匹配的组,而只留下线的其余部分?例如:
sed "s/file1.*MD5\:\(.*\)/`md5 file1.jar | awk '{print $4}'`/"
Run Code Online (Sandbox Code Playgroud)
您可以使用搜索来指定要匹配的行,然后使用替换中的更简单的正则表达式:
sed "/file1\.jar (MD5: [0-9A-Fa-f]*)/s/(MD5: [^)]*)/(MD5: $(md5 file1.jar | awk '{print $4}'))/"
Run Code Online (Sandbox Code Playgroud)
这使用$(...)符号来运行命令.其中最棘手的部分是序列))/"出现的结尾.第一个右括号是$(...)符号的结尾; 第二个是替换文本中的一个字符.
第一个正则表达式/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)/"
Run Code Online (Sandbox Code Playgroud)
它澄清了什么是相当大的(并且不涉及SO上的水平滚动条).您可以在线匹配模式中更精确:
md5=$(md5 file1.jar | awk '{print $4}')
sed "/^file1\.jar (MD5: [0-9A-Fa-f]\{32\})\$/ s/(MD5: [^)]*)/(MD5: $md5)/"
Run Code Online (Sandbox Code Playgroud)
这坚持正好32个十六进制数字和行尾的紧密括号.
其中一条评论问:
sed可以以这样的方式操作,即替换字符串只替换搜索模式中的匹配组吗?例如,给定
's/A B \(D\)/C/',它输出A B C.
如果我理解(澄清)问题,那么你可以通过适当的捕获来做你想做的事 - 但是替换部分必须准确指定你想要的输出(没有你想要的快捷方式).因此,对于该示例,您可以编写如下内容:
s/\(A B \)\(D\)/\1C/
Run Code Online (Sandbox Code Playgroud)
(捕获\(D\)不需要捕获括号,因为捕获的材料不用于替换,您可以编写以下任一项:
s/\(A B \)D/\1C/
s/\(A B\) D/\1 C/
Run Code Online (Sandbox Code Playgroud)
你也可以这样做:
/A B / s/D/C/
Run Code Online (Sandbox Code Playgroud)
这有一个搜索(对于A B序列),然后替补查找D并替换它C.这基本上是主要答案所暗示的.您也可以这样做:
/\(A B\) D/ s//\1 C/
Run Code Online (Sandbox Code Playgroud)
"空搜索"应该重复匹配,但必须完整地写出替换,这实际上与以前的命令之一相同:
s/\(A B\) D/\1 C/
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10961 次 |
| 最近记录: |