Bash modificando o texto entre as linhas marcadas

0

Eu tenho um arquivo com mais de 8000 linhas. O arquivo é dividido em seções, cada seção é rotulada com texto como ## C, ## T, ## N. Eu tenho que modificar algumas linhas no arquivo. Eu usei o comando SED para marcar as linhas entre esses marcadores. Eu sou novo no Bash, então eu gostaria de receber ajuda. Eu tenho que modificar o texto entre esses marcadores

##C
##A - beginning marker (must be next row after ##C)
text lines, some of them I have to modify
text lines, some of them I have to modify
##B -end marker

Até agora eu tenho este comando para marcar linhas entre marcadores

sed -e '/##A/,/##B/{}' file.txt

As linhas são formatadas assim:

ZDMAD BELCH 0 0 25 26 30 50

Meu objetivo é alterar algumas colunas em linhas específicas. Por exemplo: Quando a primeira coluna é ZDMAD, altere a terceira coluna para 15.

Eu usei esta pergunta resolvida para o meu maior progresso

    
por pesekvi 04.07.2018 / 14:22

1 resposta

0

Como você sabe como fazer sed agir apenas entre os marcadores, seu problema real é que você ainda não pode "alterar algumas colunas". Isso pode ser complicado porque sed não sabe sobre colunas.

For example: When the first column is ZDMAD change 3rd column to 15.

Talvez este exemplo em particular possa ser resolvido em sed , mas em um caso geral de manipulação de colunas awk é melhor porque divide registros em campos e opera nesse nível de abstração.

Isso funciona no meu Debian:

awk '
BEGIN {
   marked=0
   markA="##A"
   markZ="##B"
}
$1==markZ {marked=0}
$1=="ZDMAD" && marked==1 {$3=15}
$1==markA {marked=1}
{print $0}
' file.txt

O procedimento:

  1. Defina variáveis úteis no início (ou seja, apenas uma vez); começar em um estado "não marcado".

Depois, para cada registro:

  1. Se o primeiro campo for o marcador final, vá para um estado "não marcado".
  2. Se a condição for atendida enquanto estiver em um estado "marcado", faça o trabalho.
  3. Se o primeiro campo for o marcador inicial, vá para um estado "marcado".
  4. Imprima o registro inteiro.

Observe que o procedimento verifica primeiro o marcador final, faz o trabalho e verifica o marcador inicial por último. O ponto é que não deve manipular linhas de marcação. Em seu exemplo, a condição ( ZDMAD ) não pode corresponder a nenhuma linha de marcador, portanto, uma sequência diferente não seria um problema; mas, em geral, você deve levar isso em consideração.

    
por 05.07.2018 / 09:06