Regex 使用sed-linux从行中筛选一些文本

Regex 使用sed-linux从行中筛选一些文本,regex,awk,sed,grep,Regex,Awk,Sed,Grep,我在文件中有以下内容: NAME=ALARMCARDSLOT137 TYPE=2 CLASS=116 SYSPORT=2629 STATE=U ALARM=M APPL=" " CRMPLINK=CHASSIS131 DYNDATA="GL:1,15 ADMN:1 OPER:2 USAG:2 STBY:0 AVAL:0 PROC:0 UKNN:0 INH:0 ALM:20063;1406718801," 我只想使用sed过滤掉NAME、SYSPORT和ALM字段,请尝试下面的sed命令过滤掉N

我在文件中有以下内容:

NAME=ALARMCARDSLOT137 TYPE=2 CLASS=116 SYSPORT=2629 STATE=U ALARM=M APPL=" " CRMPLINK=CHASSIS131 DYNDATA="GL:1,15 ADMN:1 OPER:2 USAG:2 STBY:0 AVAL:0 PROC:0 UKNN:0 INH:0 ALM:20063;1406718801,"

我只想使用sed过滤掉NAME、SYSPORT和ALM字段,请尝试下面的sed命令过滤掉NAME、SYSPORT、ALM字段

$ sed 's/.*\(NAME=[^ ]*\).*\(SYSPORT=[^ ]*\).*\(ALM:[^;]*\).*/\1 \2 \3/g' file
NAME=ALARMCARDSLOT137 SYSPORT=2629 ALM:20063
为什么不使用grep呢

使用文本进行测试:

kent$  echo 'NAME=ALARMCARDSLOT137 TYPE=2 CLASS=116 SYSPORT=2629 STATE=U ALARM=M APPL=" " CRMPLINK=CHASSIS131 DYNDATA="GL:1,15 ADMN:1 OPER:2 USAG:2 STBY:0 AVAL:0 PROC:0 UKNN:0 INH:0 ALM:20063;1406718801,"'|grep -oE 'NAME=\S*|SYSPORT=\S*|ALM:[^;]*'
NAME=ALARMCARDSLOT137
SYSPORT=2629
ALM:20063
这是另一个awk

每当输入文件中存在name=value对时,我发现最好先创建一个数组,将名称映射到值,然后使用您关心的字段的名称对数组进行操作。例如:

$ cat tst.awk
function bldN2Varrs(    i, fldarr, fldnr, subarr, subnr, tmp ) {
    for (i=2;i<=NF;i+=2) { gsub(/ /,RS,$i) }

    split($0,fldarr,/[[:blank:]]+/)
    for (fldnr in fldarr) {
        split(fldarr[fldnr],tmp,/=/)
        gsub(RS," ",tmp[2])
        gsub(/^"|"$/,"",tmp[2])
        name2value[tmp[1]] = tmp[2]

        split(tmp[2],subarr,/ /)
        for (subnr in subarr) {
            split(subarr[subnr],tmp,/:/)
            subName2value[tmp[1]] = tmp[2]
        }
    }
}

function prt( fld, subfld ) {
    if (subfld) print fld "/" subfld "=" subName2value[subfld]
    else        print fld            "=" name2value[fld]
}

BEGIN { FS=OFS="\"" }
{
    bldN2Varrs()
    prt("NAME")
    prt("SYSPORT")
    prt("DYNDATA","ALM")
}

若20063 ;;1406718801,不是ALM字段所需的值,您只需调整数组构造函数以满足您的条件即可。希望字段的顺序与示例中的顺序相同。所以我们可以假设,如果没有字段值包含一个过滤器值,并且每个记录返回3行…显示您的预期输出。例如,不清楚ALM字段的值是20063还是20063;1406718801或20063;1406718801,或者别的什么。
awk -F" |;" -v RS=" " '/NAME|SYSPORT|ALM/ {print $1}'
NAME=ALARMCARDSLOT137
SYSPORT=2629
ALM:20063
$ cat tst.awk
function bldN2Varrs(    i, fldarr, fldnr, subarr, subnr, tmp ) {
    for (i=2;i<=NF;i+=2) { gsub(/ /,RS,$i) }

    split($0,fldarr,/[[:blank:]]+/)
    for (fldnr in fldarr) {
        split(fldarr[fldnr],tmp,/=/)
        gsub(RS," ",tmp[2])
        gsub(/^"|"$/,"",tmp[2])
        name2value[tmp[1]] = tmp[2]

        split(tmp[2],subarr,/ /)
        for (subnr in subarr) {
            split(subarr[subnr],tmp,/:/)
            subName2value[tmp[1]] = tmp[2]
        }
    }
}

function prt( fld, subfld ) {
    if (subfld) print fld "/" subfld "=" subName2value[subfld]
    else        print fld            "=" name2value[fld]
}

BEGIN { FS=OFS="\"" }
{
    bldN2Varrs()
    prt("NAME")
    prt("SYSPORT")
    prt("DYNDATA","ALM")
}
$ awk -f tst.awk file
NAME=ALARMCARDSLOT137
SYSPORT=2629
DYNDATA/ALM=20063;1406718801,