使用sed

时间:2018-05-23 15:44:59

标签: regex awk sed

我已从实用程序预先生成配置文件。如何提取由'),分隔的参数字符串,该字符串可能跨越多行,也可能不跨越多行?

FILE1看起来像这样 - PARM3跨越多行:

OPERAND      ID          = 'XXXX',
             ....
             PARM3       = ( 'VALUE3A',
                              ....
                             'VALUE3n'),
             PARM4       = ( 'VALUE4',
                              ....
                             'VALUE4n'),
                              ....

FILE2可能如下所示 - PARM3不会跨越多行:

OPERAND      ID          = 'XXXX',
             ....
             PARM3       = ( 'VALUE3A'),
             PARM4       = ( 'VALUE4',
                              ....
                              'VALUE4n'),
             ....

对于FILE1,如果分隔符'),位于另一行,则提取很好

sed -n "/.* PARM3 .*/,/')\,/p" FILE1

输出:

  PARM3       = ( 'VALUE3A',
                  ....
                  'VALUE3n'),

对于FILE2,如果分隔符'),位于同一行,则提取无效

sed -n "/.* PARM3 .*/,/')\,/p" FILE2

输出:

        PARM3       = ( 'VALUE3A'),
        PARM4       = ( 'VALUE4',
                         ....
                        'VALUE4n'),

如何使用sed修复此sed语句只处理可能在同一行上的分隔符?

3 个答案:

答案 0 :(得分:1)

[编辑]更简单:

sed -n '/PARM3/,/)/{p;/)/q}' file

sed的一种方式:

sed -n '/PARM3/{:a;/)/{p;q};N;ba}' file

细节:

/PARM3/ {     # if PARM3 is found
    :a            # define a label "a"
    /)/ {         # if ) is found
        p             # print the pattern space
        q             # quit
    }
    N             # append the next line to the pattern space
    ba            # go to label a
}

答案 1 :(得分:1)

您可以使用此gnu-awk命令使用自定义RS

awk -v RS='[[:blank:]]*PARM3[[:blank:]]*=[[:blank:]]*\\([^)]*\\),[[:blank:]]*' 'RT{print RT}' file

对于file1,它给出:

     PARM3       = ( 'VALUE3A',
                      ....
                     'VALUE3n'),

对于file2,它给出:

    PARM3       = ( 'VALUE3A'),

答案 2 :(得分:0)

如果您有GNU grep,可以使用其-z选项将完整输入视为一行:

$ grep -Ezo '\s+PARM3\s+=\s+\([^)]*\)' FILE2

             PARM3       = ( 'VALUE3A',
                              ....
                             'VALUE3n')

-o只保留匹配项,-E启用扩展正则表达式。

正则表达式搜索PARM3 =,其中包含任意数量的空格,然后是(,然后搜索所有内容,包括结束)。为避免贪婪匹配,我使用[^)](“不是右括号”)。

如果你不需要前导空格,可以跳过它们,如果你需要尾随逗号,可以添加(可选,如果它不存在):

$ grep -Ezo 'PARM3\s+=\s+\([^)]*\),?' infile
PARM3       = ( 'VALUE3A',
                              ....
                             'VALUE3n'),

或获得正确的对齐方式,但不是匹配前的换行符:

$ grep -Ezo '[[:blank:]]*PARM3\s+=\s+\([^)]*\),?' infile
             PARM3       = ( 'VALUE3A',
                              ....
                             'VALUE3n'),