Apagando o padrão de 2 linhas com sed / grep / whatever

2

Eu tenho um arquivo de log cvs enorme que, limpo das informações inúteis, lê algo como

Working file: unmodifiedfile1.c
================
Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: unmodifiedfile2.h
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================
Working file: unmodifiedfile3.h

Gostaria de limpar as linhas relacionadas a arquivos não modificados:

Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================

O padrão a corresponder é

Working file: FILENAME
================

O que consegui fazer até agora é o seguinte:

sed '/Working file:/ N ; s/\n/PLACEHOLDER/' changelog.txt |
grep -v 'PLACEHOLDER===' |
sed 's/PLACEHOLDER/\n/ 

Tenho certeza, no entanto, que existe uma solução mais limpa que minha ignorância me impede ... (também, um bônus seria poder apagar a última linha, se necessário)

P.S.

Uma saída terminando com:

================
Working file: unmodifiedfile3.h

também é aceitável

    
por Davide 08.09.2016 / 15:19

2 respostas

1
sed '/Working file:/ N ; s/\n/PLACEHOLDER/' changelog.txt |
grep -v 'PLACEHOLDER===' |
sed 's/PLACEHOLDER/\n/ 

pode, de fato, ser encurtado para:

$ sed '/Working file:/{N;/===/d}' changelog.txt 
Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================
Working file: unmodifiedfile3.h


  • Para remover todas as linhas que contenham Working file: e a linha seguinte, se contiver === , bem como a linha final, se contiver Working file:

Obrigado @ilkkachu pela sugestão. Se o padrão precisar ser combinado no início da linha, use ^Working file:

$ cat ip.txt 
Working file: 123
================
Working file: f1
----------------------------------
revision 1.3
Fixed some bug
================
Working file: abc
================
Working file: file
----------------------------------
revision 1.1
Added some feature
================
Working file: xyz

$ sed '/Working file:/{N;/===/d}' ip.txt | sed '${/Working file:/d}' 
Working file: f1
----------------------------------
revision 1.3
Fixed some bug
================
Working file: file
----------------------------------
revision 1.1
Added some feature
================
    
por 08.09.2016 / 15:54
3

sed

Isso deve se aproximar do que você procura:

<cvslog sed -n '/Working file/ { N; /\n=\+$/b; :a; N; /\n=\+$/!ba; p; }'

Saída:

Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================

Explicação

Aqui está o mesmo script sed com comentários:

/Working file/ {
  N                 # append next line to pattern space
  /\n=\+$/b         # is it a file separator -> next file
  :a
  N                 # append next line to pattern space
  /\n=\+$/!ba       # isn't it a file separator -> read next line
  p                 # otherwise print accumulated text
}

awk

Se você disser awk para usar a linha separadora de arquivos como o separador de registros ( RS ), será bastante simples definir um critério de seleção sensato:

<cvslog awk 'NF>2' RS='\n=+\n' FS='\n' ORS='\n\n'

Saída:

Working file: modifiedfile1.h  
----------------------------------
revision 1.3
Fixed some bug

Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature

bash e coreutils

Apenas por diversão:

csplit cvslog '/=\{16\}/1' '{*}'
wc -l xx* | 
head -n-1 | 
while read n f; do 
  if (( n > 2 )); then 
    cat $f
  fi
done

Saída:

Working file: modifiedfile1.h
----------------------------------
revision 1.3
Fixed some bug
================
Working file: modifiedfile2.h
----------------------------------
revision 1.1
Added some feature
================
    
por 08.09.2016 / 15:52