提问人:Ali J. Ghandour 提问时间:10/19/2023 最后编辑:Ali J. Ghandour 更新时间:10/21/2023 访问量:114
sed:替换特定关键字后面的下一个单词
sed: replace immediate next word coming after a particular keyword
问:
在 GitHub 操作中,将推送请求合并到 main 时,我想将笔记本中出现的分支名称替换为 .main
例如,给定以下行:git clone --branch fork1 https://somrepo.git
使用下面的正则表达式,直到行尾的所有值都被替换,但是,我的意图是简单地替换为:fork1
main
sed -i 's/\(--branch\)\(.*\)/\1 main/'
另一个例子,给出下面的行:"https://colab.research.google.com/github/user/repo/blob/fork2/notebook.ipynb"
使用下面的正则表达式,直到行尾的所有值都被替换,但是,我的意图是简单地替换为:fork2/
main/
sed -i 's/\(blob\/\)\(.*\)/\1 main\//'
编辑:
为了澄清我的问题,我的 github 操作用例是在合并 PR 后将分支名称替换为多个文件。不,在这种情况下不起作用,因为ref_name将指向合并分支,而不是创建 PR 的初始分支。main
GITHUB_REF_NAME
name: Update Branch Name
on:
push:
branches:
- main
jobs:
restore_main_branch_name:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Update .ipynb files
run: |
sed -i "s|${{ github.ref_name }}|main|g" colabLaunchScript.ipynb
- name: Commit changes
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Actions"
git commit -am "Restore main branch name in .ipynb file"
git push -u origin main
答:
第一种情况:匹配空格,后跟一系列非空格。将非空格替换为main
s/\(--branch\)\s\+\(\S\+\)/\1 main/
正如用户 tripleee 所指出的,您的 sed 版本可能不支持。或者,您可以使用:\s
\S
s/\(--branch\)[[:space:]]\+\([^[:space:]]\+\)/\1 main/
第二种情况:改为:/fork1/
/main/
s#/fork1/#/main/#
注意:在这种情况下,选择的替换分隔符是通常首选的,因此不必对其进行转义。#
/
/
评论
\s
\S
sed
[:space:]
要替换 之后的下一个非空格标记,请匹配后跟一个或多个空格,后跟最长的非空格字符序列。--branch
--branch
sed 's/\(--branch *\)[^ ]*/\1main/'
(如果你有这个可以简化为sed -E
sed -E 's/(--branch +)[^ ]*/\1main/'
但这是一个非 POSIX 扩展。
您的尝试只是匹配所有字符,直到行的末尾(即任何字符尽可能多地重复)。.*
.
*
要匹配下一个非空格、非斜杠标记后,匹配非空格、非斜杠字符的数量尽量多;并且可能使用与斜杠不同的分隔符来简化自己的事情;/blob/
[^ /]
*
sed 's%\(/blob/\)[^ /]*%\1main%'
如果需要替换字符串来自 shell 变量,则需要使用双引号而不是单引号;然后,这需要您在贝壳会吃掉其中一些的地方使用更多的反斜杠。一个简单的解决方法是在双引号字符串旁边使用单引号字符串,这样你就不需要添加大量的反斜杠;
sed 's%\(/blob/\)[^ /]*%\1'"$branch%"
Stack Overflow 正则表达式
标记信息页面包含常见初学者问题的答案和学习材料的链接。
评论
上一个:删除模式之间的逗号
评论
[^ ]*
.*
s%/fork1/%/main/%
-i
a
a
fork1/