3

首先,我知道遵循这种格式的普通 conf 文件(我不知道它叫什么)通常有一个空行分隔部分,这使得这个问题更容易解决。但我想知道是否有一种小而干净的方法可以在 awk 中仅打印以下文件的第 2 节(称为 test.conf):

[section1]    
a = 1         
b = 2         
[section2]    
c = 3         
d = 4         
[section3]    
e = 5         
d = 6

我的第一个猜测失败了:

bash-3.2$ awk '/^\[section2\]$/,/^\[/' test.conf
[section2]

因为同一行匹配开始和结束范围分隔符。我觉得有一种更好的方法来做到这一点,而不是在进入第 2 节时设置一些变量,然后在进入下一节时将其关闭。有人知道吗?

4

5 回答 5

5

AWK 解决方案

INI 文件通常不保证其部分的顺序,因此以下内容有些脆弱,因为它依赖于顺序。但是,它非常短,可以与您定义的语料库一起使用。

$ gawk '/section3/ {exit}; /section2/,/section3/ {print}' /tmp/foo.ini
[section2]
c=3
d=4

备择方案

  • 使用 sed 删除行。简短且不依赖于顺序,但可能有点神秘。

    $ sed -n '/section2/, /^\[/ { /section[^2]/d; p }' /tmp/foo.ini
    [section2]
    c=3
    d=4
    
  • 使用 Perl 的触发器运算符。非常灵活。

    $ perl -ne 'push(@lines, $_) if /section2/.../section3/;
                END {pop @lines; print @lines}' /tmp/foo.ini
    [section2]
    c=3
    d=4
    
于 2013-10-08T05:05:51.753 回答
3

这应该这样做

awk '/\[section2\]/,/\[section3\]/{if ($0 !~ /\[section3\]/) print}' test.conf

或者更容易使用 sed

sed -n '/\[section2\]/,/\[section3\]/{/\[section3\]/!p}' test.conf
于 2013-10-08T05:01:44.243 回答
2

你可以试试这个:

awk -vRS=[ /section2/ test.conf

结果并不完美:

section2]    
c = 3         
d = 4         

另一个命令:

awk -vRS=[ '/section2/{print RS$0}' test.conf
于 2013-10-08T05:06:16.107 回答
1

不是最短的,但至少部分排序不会破坏它:

$ awk '/^\[section2/ {p=1; next}; /^\[/ {p=0}; p'  test.conf
c = 3         
d = 4

并且适用于每个 awk。

于 2013-10-08T08:12:48.137 回答
0

其他awk

awk '/section3/ {exit} /section2/ {f=1} f' /tmp/foo.ini
于 2013-10-08T05:35:36.733 回答