我正在尝试创建一个脚本,该脚本将在sources.list(Ubuntu)中启用其他东西启用源存储库。您可能知道或不知道存储库文件的格式是这样的:
deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted
# deb-src http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted
# etc.
所以我想启用源存储库(使用deb-src取消注释行),但仅限于未注释的deb行之前的那些。 GNU sed应该是完美的,但我无法做到这一点。 这就是我现在所拥有的:
sed -i 's/^# deb-src/deb-src/gm' /etc/apt/sources.list
我想要的是这样的东西,但它应该只替换注释行而不是所有内容:
sed -i 's/^deb .*$^# deb-src/deb-src/gm' /etc/apt/sources.list
那么有没有办法为sed制作只能替换匹配字符串部分的正则表达式?
答案 0 :(得分:2)
我个人更喜欢awk/perl
来匹配两个连续的行
awk '/^# *deb-src/ && p ~ /^deb /{sub(/^# */, "")} {p=$0} 1'
p=$0
保存上一行/^# *deb-src/ && p ~ /^deb /
如果当前行以评论开头并且 deb-src 且上一行以 deb sub(/^# */, "")
删除评论1
以惯用方式打印当前记录,包括所做的任何更改
使用sed
,您可能需要类似
sed '/^deb /{n; /^# *deb-src/ s/# *//p; D}'
或
sed '$!N; /^deb .*\n# *deb-src/ s/\n# */\n/p; D'
但我不太确定这是否可以处理所有情况。有关详细信息,请参阅https://www.gnu.org/software/sed/manual/sed.html#advanced-sed。只有在模式空间中有多行时,m
修饰符才会起作用。默认情况下,sed
使用换行作为行分隔符,并且在模式空间中只有单行。手动链接有更多详细信息
答案 1 :(得分:2)
除-z
之外使用-r
:
sed -rz -i 's/^(deb .*\s+)^# deb-src/\1deb-src/gm' /etc/apt/sources.list
捕获组是必要的,以便更换它们。
答案 2 :(得分:0)
如果您的sources.list仅由以下行组成:
deb http://................
deb-src http://............
# deb http://...........
# deb-src http://.........
deb http://................
# deb-src http://............
并且您不必删除注释行,您可以通过仅修改以deb
开头的未注释的行来创建新的sources.list文件:
grep -A1 "^deb " sources.list | sed "s/# deb-src/deb-src/g"
使用此选项,您只会选择以^deb
开头的行和下一行,然后取消注释下一行(以# deb-src
开头的那一行)
然后,您可以将输出发送到新文件,然后可以通过sources.list重命名:
grep -A1 "^deb " sources.list | sed "s/# deb-src/deb-src/g" > sources_new && mv -f sources_new sources.list
但是只有在sources.list文件中有这种语法时才会有效。