Bash awk/sed extrai várias strings de uma única string grande usando palavras-chave

Bash awk/sed extrai várias strings de uma única string grande usando palavras-chave

Por favor, ajude-me a descobrir como extrair várias substrings com base em palavras-chave. Tenho lutado com diferentes métodos usando delimitadores

Minha entrada:

Inventory for 30844-ap01 NAME: AP1800 , DESCR: Cisco Aironet 1800 Series (IEEE 802.11ac) Access Point PID: AIR-AP1832I-E-K9, VID: V03, SN: KWC21420CKU
Inventory for ckh.hq-ap99 NAME: AP2700 , DESCR: Cisco Aironet 2700 Series (IEEE 802.11n) Access Point PID: AIR-CAP2702I-E-K9, VID: V03, SN: FCW2007N0ZQ
Inventory for AP0042.6843.ab78 NAME:  , DESCR:  PID: AIR-CAP1702I-E-K9, VID: V, SN: FCZ201622NY

Saída desejada:

30844-ap01 AIR-AP1832I-E-K9 KWC21420CKU
ckh.hq-ap99 AIR-CAP2702I-E-K9 FCW2007N0ZQ
AP0042.6843.ab78 AIR-CAP1702I-E-K9 FCZ201622NY

A primeira string é qualquer coisa entre "Inventário para" e o próximo espaço

A segunda string é qualquer coisa entre "PID:" e a vírgula

A terceira string é uma string de 11 caracteres após "SN:"

Responder1

Usando qualquer sed em qualquer shell em cada caixa Unix:

$ sed 's/Inventory for \([^ ]*\).*PID: \([^,]*\).*SN:/\1 \2/' file
30844-ap01 AIR-AP1832I-E-K9 KWC21420CKU
ckh.hq-ap99 AIR-CAP2702I-E-K9 FCW2007N0ZQ
AP0042.6843.ab78 AIR-CAP1702I-E-K9 FCZ201622NY

Responder2

Acho que a melhor ferramenta para esses trabalhos tem grepos seguintes PCRErecursos:

grep -Po '(?<=Inventory for )[^ ]+|(?<=PID: )[^,]+|(?<=SN: ).{11}' data

Mas isso tem a desvantagem de imprimir cada partida em linhas separadas:

30844-ap01
AIR-AP1832I-E-K9
KWC21420CKU
ckh.hq-ap99
AIR-CAP2702I-E-K9
FCW2007N0ZQ
AP0042.6843.ab78
AIR-CAP1702I-E-K9
FCZ201622NY

Então, vamos mudar perle fazer o mesmo:

perl -lne ' $i = $& if /(?<=Inventory for )[^ ]+/; $p = $& if /(?<=PID: )[^,]+/ ; $s = $& if /(?<=SN: ).{11}/; print join " ", $i, $p, $s' data

Imprimir:

30844-ap01 AIR-AP1832I-E-K9 KWC21420CKU
ckh.hq-ap99 AIR-CAP2702I-E-K9 FCW2007N0ZQ
AP0042.6843.ab78 AIR-CAP1702I-E-K9 FCZ201622NY

Responder3

Usando gawk:

awk '{a=b=c=$0;
gsub(/^.*Inventory for | .*$/,"",a);
gsub(/^.*PID: |,.*$/, "",b);
sub(/^.*SN: /,"",c); c=substr(c,1,11);
print a,b,c}' input

As três primeiras variáveis a​​e são definidas para o registro de entrada atual ( ). Em seguida, a função integrada altera regex para string vazia ( ). A regex aqui usa alternância tem dois padrões e . A alternância permite padrões alternativos em regex com . Desde o início da linha ( ) até é alterado para . Isso significa que todos os caracteres do início da linha até a primeira string que desejamos são removidos. Da mesma forma, do espaço (após a primeira string que queremos) até o final da linha são alterados para . Da mesma forma, tem dois padrões alternativos e . Ambos são alterados para .bc$0gsub()""(/^.*Inventory for | .*$//^.*Inventory for // .*$/|gsub()^Inventory for""""/^.*PID: |,.*$//^.*PID: //,.*$/""

Em seguida, sub()muda /^.*SN: /para uma string vazia e substr(c,1,11)pega uma string de 11 caracteres de c.

informação relacionada