Existe uma maneira de imprimir 2 linhas (se houver) antes e depois de um alvo ou imprimir um espaço reservado, se não?

2

Eu não sou falante nativo de inglês, então espero ser claro.

Eu sei sobre grep -C 2 "TARGET" inputfile para selecionar 2 linhas antes e depois da linha do TARGET, mas não consigo usá-lo para gerenciar meu problema. Eu tenho arquivos estruturados assim

1 0 value1 value2 value3
2 H value1 value2 value3
3 H value1 value2 value3
4 H value1 value2 value3
5 H value1 value2 value3
6 0 value1 value2 value3
7 0 value1 value2 value3
8 H value1 value2 value3
9 0 value1 value2 value3

com várias linhas. A solução necessária seria um arquivo como este

X X X X X
1 0 value1 value2 value3
2 H value1 value2 value3 *
3 H value1 value2 value3 
4 H value1 value2 value3

1 0 value1 value2 value3
2 H value1 value2 value3
3 H value1 value2 value3 *
4 H value1 value2 value3 
5 H value1 value2 value3

... all the other till

6 0 value1 value2 value3
7 0 value1 value2 value3
8 H value1 value2 value3 *
9 0 value1 value2 value3
X X X X X

onde o TARGET é "H", * é para indicar a linha selecionada (mas eu não preciso de * no arquivo de saída) e X são espaços reservados para ajustar o número de linhas antes ou depois do alvo! Eu tentei também com awk e sed, sem resultados.

    
por bonimba3 07.02.2014 / 14:49

2 respostas

4

A mesma abordagem de Glenn Jackman, mas com um buffer circular em vez de girar o buffer em todas as entradas:

awk -v N=2 -v TARGET=" H " -v PLACE="X X X X X" '
  function check(n, s,     i) {
    a[n%NN]=s
    if (n>N&&a[(n-N)%NN]~TARGET) {
      for (i=n+1;i<=n+NN;++i)
        print a[i%NN]
      print ""
    }
  }

  BEGIN{
    NN=2*N+1
    a[0]=PLACE
    for (i=1;i<=N;++i) { getline a[i]; a[i+N]=PLACE }
  }

  { check(NR,$0) }

  END{
    for (i=NR+1;i<=NR+N;++i) check(i,PLACE)
  }'
    
por 07.02.2014 / 17:44
4

Isso vai te dar a maior parte do caminho:

awk -v n=2 -v target=" H " '
    BEGIN {
        lines[0]=""
        for (i=1; i<=n; i++) {
            lines[i]="X X X X X"
            getline; lines[n+i]=$0
        }
    }
    function rotate(i) {
        for (i=1; i<=n*2; i++) 
            lines[i-1] = lines[i]
        lines[n*2]=$0
    }
    function check(i) {
        if (lines[n] ~ target) {
            for (i=0; i<=n*2; i++) 
                print lines[i]
            print ""
        }
    }
    { rotate(); check() }
    END {
        for (i=1; i<=n; i++) {
            $0 = "X X X X X"; rotate(); check()
        }
    }
' inputfile

saídas

X X X X X
1 0 value1 value2 value3
2 H value1 value2 value3
3 H value1 value2 value3
4 H value1 value2 value3

1 0 value1 value2 value3
2 H value1 value2 value3
3 H value1 value2 value3
4 H value1 value2 value3
5 H value1 value2 value3

2 H value1 value2 value3
3 H value1 value2 value3
4 H value1 value2 value3
5 H value1 value2 value3
6 0 value1 value2 value3

3 H value1 value2 value3
4 H value1 value2 value3
5 H value1 value2 value3
6 0 value1 value2 value3
7 0 value1 value2 value3

6 0 value1 value2 value3
7 0 value1 value2 value3
8 H value1 value2 value3
9 0 value1 value2 value3
X X X X X
    
por 07.02.2014 / 16:27