如果它们少于n行,则Sed删除2个模式之间的内容

时间:2016-11-22 14:51:43

标签: linux design-patterns awk sed count

我一直在寻找一段时间,但我找不到如何做到这一点:

我有一个包含很多内容的文件+以下信息:

pool_1: &pool_prod
        - ip: 10.1.60.5
          weight: 1
        - ip: 10.1.60.6
          weight: 1

    pool_prod_nl: &pool_prod_nl
        - ip: 10.1.60.47
          weight: 1

    pool_prod_it: &pool_prod_it
        - ip: 10.1.60.65
          weight: 1
        - ip: 10.1.60.83
          weight: 1

    pool_prod_it: &pool_prod_dek
        - ip: 10.1.60.68
          weight: 1

我想保留结果:

pool_1: &pool_prod
    - ip: 10.1.60.5
      weight: 1
    - ip: 10.1.60.6
      weight: 1

pool_prod_it: &pool_prod_it
        - ip: 10.1.60.65
      weight: 1
    - ip: 10.1.60.83
      weight: 1

当我做的时候

sed -n '/pool_/,/^$/{p; /^$/q}'

我可以提取我在第一个代码中列出的一些信息,但我没有成功过滤它们,因为它们之间有相同的模式和信息,只是行数或内部出现的数量可以产生差异,但是我找不到如何制作它。

我会感激任何帮助 提前谢谢

3 个答案:

答案 0 :(得分:1)

awk救援!

$ awk -F'\n' -v RS= -v ORS='\n\n' '/pool/ && NF==5' file

pool_1: &pool_prod
        - ip: 10.1.60.5
          weight: 1
        - ip: 10.1.60.6
          weight: 1

    pool_prod_it: &pool_prod_it
        - ip: 10.1.60.65
          weight: 1
        - ip: 10.1.60.83
          weight: 1

或使用NF==5

更改NF>4

答案 1 :(得分:0)

假设您编写的sed表达式是您想要的,那么这将打印出大于5行的表达式并忽略那些不是。您可以在if语句中将该数字调整为您喜欢的任何内容。然而,这将删除输入文件的内容(在我的示例中为input.txt),因此如果您想要其他方式,则必须使用它。

#!/bin/bash

while true; do
    output_of_sed=$(sed -n '/pool_/,/^$/{p; /^$/q}' input.txt)
    output_number_of_lines=$(sed -n '/pool_/,/^$/{p; /^$/q}' input.txt | wc -l)

    sed -i "1, ${output_number_of_lines}d" input.txt

    if [[ ${output_number_of_lines} -gt 5 ]]; then
        echo "${output_of_sed}"
    fi

    if [[ ${output_number_of_lines} -le 1 ]]; then
        break;
    fi
done

答案 2 :(得分:0)

在awk中:

$ awk '/^pool/{if(c>4) print b; c=b=""}{c++; b=b (b?ORS:"") $0}' file
pool_1: &pool_prod
        - ip: 10.1.60.5
          weight: 1
        - ip: 10.1.60.6
          weight: 1

pool_prod_it: &pool_prod_it
    - ip: 10.1.60.65
      weight: 1
    - ip: 10.1.60.83
      weight: 1

说明:

/^pool/ {              # if record starts with pool
    if(c>4)            # if (buffer record) count > 4
        print b        # print buffer
    b=c=""             # reset buffer and counter
} {
    c++                # iterate counter
    b=b (b?ORS:"") $0  # build buffer with current record and ORS when needed
}

如果pool字符串实际上以空格开头,请将/^pool/更改为例如/^ *pool