Estou tentando descobrir um comando/script awk para extrair um bloco de texto de um arquivo grande. A subseção do arquivo em que estou interessado é esta:
Board Info: #512
Manufacturer: "Dell Inc."
Product: "0X3D66"
Version: "A02"
Serial: "..CN7016343F00IE."
Chassis Info: #768
As linhas Board Info e Chassis Info têm 2 espaços à esquerda, enquanto o bloco recuado tem 4. Eu gostaria de não presumir que a linha final começa com Chassis Info (pode ser outra coisa) e apenas confiar em chegar à próxima linha começando com 2 espaços.
Esse:
awk '/^\s{2}Board Info/,/^\s{2}[^B ]/' dump.txt
resolve esta instância específica, mas não funcionará se, em vez de 'Informações do chassi', a linha do bloco final começar com a letra B (por exemplo, BOM).
Se eu usar:
awk '/^\s{2}Board Info/,/^\s{2}\S*/' dump.txt
O padrão final também corresponde à linha "Informações do Quadro", então eu obtenho apenas essa linha. Como obtenho esse bloco recuado (4 espaços à esquerda) sem codificar o bloco final (como acima) e depender do padrão final ser "a próxima linha que começa com exatamente 2 espaços à esquerda"?
Supondo que haja apenas linhas recuadas com 4 caracteres de espaço em branco após o início, você pode ter certeza de que há pelo menos uma única linha recuada presente, ou então não imprima nada.
Não tenho certeza se você deseja imprimir a linha inicial e a linha de fechamento, mas você pode omitir a impressão delas se quiser, não adicionando-as ao buffer.
Você pode alterar estas linhas:
E:
Eu melhoraria seu código
seguindo o caminho, deixe
dump.txt
o conteúdo serentão
dá saída
Explicação: Alterei a condição final exigindo que a linha começasse com 2 caracteres de espaço em branco seguidos por qualquer caractere alfabético E (
&&
) NÃO (!
) sendo a linha de informações do quadro (negando a condição inicial).(testado no GNU Awk 5.3.1)
Você pode adicionar uma ação que imprimirá se houver (pelo menos) 3 caracteres de espaço em branco no início da linha, seguindo o caminho
que dará a seguinte saída
Esta
awk
solução deve funcionar com qualquer versão deawk
:Explicação:
/^ [^[:blank:]]/
corresponde a uma linha com 2 espaços no início, seguidos por qualquer caractere que não seja espaço em branco.blk = !blk
: alterna o valor do sinalizadorblk
para1
ou0
blk
no final imprime uma linha seblk
for1
Usando qualquer awk:
Em relação ao seu código original:
/start/,/end/
) costuma ser mais complicado de acertar em geral e sempre mais difícil de aprimorar do que usar uma flag (f
no meu código), o que frequentemente leva a código duplicado ou outros softwares ruins. Veja " Uma expressão de intervalo /start/,/end/ é útil no awk?" para mais informações.\s
como uma abreviação para[[:space:]]
isso, o que torna seu código não portátil, mas ambas as construções são desnecessárias de qualquer maneira quando seus espaços são apenas caracteres em branco.Um pequeno ajuste
FS
é tudo o que você precisa para um1/0
indicador de impressão sem usar intervalos de padrões: