如何用sed取消注释下一行
How to uncomment the next line with sed
我正在尝试在使用 archiso 安装 Arch 时自动自定义我的 pacman.conf 文件。
为此,我想取消 pacman 配置文件中两行的注释。
这是相关文件的摘录:
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
#[multilib]
#Include = /etc/pacman.d/mirrorlist
所以我想取消注释 multilib 块的两行,而不是 multilib-testing 块!
使用 sed 很容易取消注释块的第一行:
sed -i 's/#\[multilib]/\[multilib]/g' /etc/pacman.conf
然而,下一行与前一个块中的行完全相同(实际上在许多其他块中也是如此),所以如果我这样做:
sed -i 's/#Include =/Include =/g' pacman.conf
它将更改与该模式匹配的所有行。
我想要的是只更改[multilib]之后的特定行
我该怎么做?
当您找到 #[multilib]
行时,读取 N 行并将其附加到模式 space 中,然后删除后面的 #
换行 (\n
).
sed '/^#\[multilib]/{N;s/\n#/\n/}' file
给定您的示例其输出:
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
#[multilib]
Include = /etc/pacman.d/mirrorlist
如果awk也是一个选项:
awk 'f{sub(/^#/,"");f=0} [=12=]=="#[multilib]"{f=1} 1' file
这样您就不需要转义正则表达式激活的字符。
有一个更简单的 sed 解决方案,不需要任何多行技术:
/^#\[multilib]/ { # Match only the [multilib] line.
n # Then read the next line.
s/^#// # ... and delete the comment marker.
}
测试:
▶ cat > FILE <<EOF
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
#[multilib]
#Include = /etc/pacman.d/mirrorlist
EOF
▶ gsed -i '/^#\[multilib]/{n;s/^#//}' FILE
输出:
▶ cat FILE
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
#[multilib]
Include = /etc/pacman.d/mirrorlist
sed 用于对单个字符串执行 s/old/new,仅此而已。使用 awk:
$ awk '[=10=]=="#[multilib]"{c=2} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
[multilib]
Include = /etc/pacman.d/mirrorlist
不需要转义字符,如果您需要从 50 行而不是 2 行中删除 #,您只需将 2
更改为 50
,您不必重写脚本!如果愿意,您显然可以参数化开始字符串和要取消注释的行数:
$ awk -v beg='#[multilib]' -v num=2 '[=11=]==beg{c=num} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
[multilib]
Include = /etc/pacman.d/mirrorlist
$ awk -v beg='#[multilib-testing]' -v num=2 '[=11=]==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist
#[multilib]
#Include = /etc/pacman.d/mirrorlist
$ awk -v beg='#[multilib-testing]' -v num=5 '[=11=]==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist
[multilib]
Include = /etc/pacman.d/mirrorlist
我正在尝试在使用 archiso 安装 Arch 时自动自定义我的 pacman.conf 文件。
为此,我想取消 pacman 配置文件中两行的注释。
这是相关文件的摘录:
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
#[multilib]
#Include = /etc/pacman.d/mirrorlist
所以我想取消注释 multilib 块的两行,而不是 multilib-testing 块!
使用 sed 很容易取消注释块的第一行:
sed -i 's/#\[multilib]/\[multilib]/g' /etc/pacman.conf
然而,下一行与前一个块中的行完全相同(实际上在许多其他块中也是如此),所以如果我这样做:
sed -i 's/#Include =/Include =/g' pacman.conf
它将更改与该模式匹配的所有行。
我想要的是只更改[multilib]之后的特定行 我该怎么做?
当您找到 #[multilib]
行时,读取 N 行并将其附加到模式 space 中,然后删除后面的 #
换行 (\n
).
sed '/^#\[multilib]/{N;s/\n#/\n/}' file
给定您的示例其输出:
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
#[multilib]
Include = /etc/pacman.d/mirrorlist
如果awk也是一个选项:
awk 'f{sub(/^#/,"");f=0} [=12=]=="#[multilib]"{f=1} 1' file
这样您就不需要转义正则表达式激活的字符。
有一个更简单的 sed 解决方案,不需要任何多行技术:
/^#\[multilib]/ { # Match only the [multilib] line.
n # Then read the next line.
s/^#// # ... and delete the comment marker.
}
测试:
▶ cat > FILE <<EOF
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
#[multilib]
#Include = /etc/pacman.d/mirrorlist
EOF
▶ gsed -i '/^#\[multilib]/{n;s/^#//}' FILE
输出:
▶ cat FILE
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
#[multilib]
Include = /etc/pacman.d/mirrorlist
sed 用于对单个字符串执行 s/old/new,仅此而已。使用 awk:
$ awk '[=10=]=="#[multilib]"{c=2} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
[multilib]
Include = /etc/pacman.d/mirrorlist
不需要转义字符,如果您需要从 50 行而不是 2 行中删除 #,您只需将 2
更改为 50
,您不必重写脚本!如果愿意,您显然可以参数化开始字符串和要取消注释的行数:
$ awk -v beg='#[multilib]' -v num=2 '[=11=]==beg{c=num} c&&c--{sub(/#/,"")} 1' file
#[multilib-testing]
#Include = /etc/pacman.d/mirrorlist
[multilib]
Include = /etc/pacman.d/mirrorlist
$ awk -v beg='#[multilib-testing]' -v num=2 '[=11=]==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist
#[multilib]
#Include = /etc/pacman.d/mirrorlist
$ awk -v beg='#[multilib-testing]' -v num=5 '[=11=]==beg{c=num} c&&c--{sub(/#/,"")} 1' file
[multilib-testing]
Include = /etc/pacman.d/mirrorlist
[multilib]
Include = /etc/pacman.d/mirrorlist