Padrões e processamento de arquivos

3

Digamos que eu tenha que executar essas ações a partir de um arquivo de entrada:

  • extrair o n-ésimo campo de uma linha que começa com um determinado padrão ( no exemplo: 2º campo da linha que começa com o padrão 'nome' )

  • imprime o conteúdo do campo no início de cada linha seguinte, enquanto a linha não começa com o padrão selecionado

  • quando uma nova linha correspondente ao padrão for encontrada, repita as etapas 1 e 2

Atualmente estou fazendo isso usando Python, mas seria melhor usar algo leve e rápido na linha de comando (como o awk, por exemplo).

Exemplo de entrada

name    NAME_A
inf     field_A1
name    NAME_B 
inf field_B1
inf field_B2

Resultado esperado:

name    NAME_A
NAME_A  inf field_A1
name    NAME_B 
NAME_B  inf field_B1
NAME_B  inf field_B2
    
por dovah 29.07.2014 / 13:29

3 respostas

2

Esta pode ser uma maneira de fazer isso. Observe que o formato pode variar dependendo dos separadores de campo que você indicar - aqueles que você pode definir com FS e OFS :

$ awk -v n=2 '/^name/ {a=$(n); print; next} {print a, $0}' file
name    NAME_A
NAME_A inf  field_A1
name    NAME_B 
NAME_B inf  field_B1
NAME_B inf  field_B2

Explicação

  • -v n=2 define o número do campo para copiar quando o padrão é encontrado.
  • /^name/ {a=$(n); print; next} se a linha começar com o padrão fornecido, armazene o campo especificado e imprima a linha.
  • {print a, $0} caso contrário, imprima a linha atual com o valor armazenado primeiro.

Você pode generalizar a parte do padrão em algo como:

awk -v n=2 -v pat="name" '$1==pat {a=$(n); print; next} {print a, $0}' file
    
por 29.07.2014 / 13:33
1
sed '/^name  */{h;s///;x;n;};G;s/\(.*\)\n\(.*\)/        /' <<\DATA
name    NAME_A
inf     field_A1
name    NAME_B 
inf field_B1
inf field_B2
DATA

OUTPUT

name    NAME_A
NAME_A  inf     field_A1
name    NAME_B 
NAME_B  inf field_B1
NAME_B  inf field_B2

sed h olds cada nome linha e, em seguida, remove do mesmo padrão que correspondeu, então troca espaço e espaço padrão antes de imprimir,

Em todas as outras linhas, G etspacespace é anexado ao espaço padrão com uma nova linha interveniente. Em seguida, apenas troca os dois lados dessa nova linha e a substitui por uma guia.

    
por 29.07.2014 / 13:54
1

Isso pode funcionar:

awk '{print $0 ~ pat ? $0 : p OFS $0   }$0 ~ pat{ p = $NF }' pat='name' file
    
por 31.07.2014 / 21:46

Tags