Eu uso isso
cat foo.txt | sed '/bar/d'
para remover linhas que contêm a sequência bar
no arquivo.
Gostaria, no entanto, de remover essas linhas e a linha logo após . De preferência em sed
, awk
ou outra ferramenta disponível no MinGW32.
É uma espécie de reverso do que eu posso entrar em grep
com -A
e -B
para imprimir linhas correspondentes, bem como linhas antes / depois da linha correspondido.
Existe alguma maneira fácil de conseguir isso?
text-processing
sed
awk
replace
jakub.g
fonte
fonte
Respostas:
Se você possui o GNU sed (Linux ou Cygwin não incorporado):
Se você tiver
bar
duas linhas consecutivas, isso excluirá a segunda linha sem analisá-la. Por exemplo, se você tiver um arquivo de 3 linhasbar
/bar
/foo
, afoo
linha permanecerá.fonte
bar
s consecutivos, portanto, este é super fácil de lembrar.sed '/bar/d'
se você quiser apenas "Remover linha contendo determinada string" e não a próxima.sed '/math/q'
sed '/bar/d'
Se
bar
ocorrer em linhas consecutivas, você poderá:que pode ser adaptado para excluir mais de 2 linhas, alterando as 2 acima com o número de linhas a serem excluídas, incluindo a correspondente.
Caso contrário, é fácil concluir
sed
com a solução @MichaelRollins ou:fonte
/bar/
com/bar|baz|whatever/
. Nessased
sintaxe parece não funcionar.sed
para usar expressões regulares "estendidas". Mais informações aqui: gnu.org/software/sed/manual/html_node/… . Observe que isso também é aplicávelgrep
. Aqui está o meu próprio exemplo de trabalho:echo $'0a\n1b\n2c' | sed '/0a\|1b/d'
.Não sou fluente no sed, mas é fácil fazê-lo no awk:
O script awk diz: para uma linha que contém bar, pegue a próxima linha (getline) e, em seguida, pule todo o processamento subsequente (próximo). O padrão 1 no final imprime as linhas restantes.
Atualizar
Como apontado no comentário, a solução acima não funcionou com consecutivas
bar
. Aqui está uma solução revisada, que leva em consideração:Agora continuamos lendo para pular todas as linhas / bar /.
fonte
grep -A
100%, você também precisa manipular qualquer número debar
linhas consecutivas corretamente (removendo o bloco inteiro e 1 linha depois).Você vai querer usar os recursos de script do sed para fazer isso.
Dados de amostra:
O comando "N" acrescenta a próxima linha de entrada no espaço do padrão. Combinada com a linha da correspondência de padrões (/ bar /), serão as linhas que você deseja excluir. Você pode excluir normalmente com o comando "d".
fonte
sed -e '/bar/{N;d}' sample1.txt
Se qualquer linha imediatamente após uma partida for removida, seu
sed
programa terá que considerar partidas consecutivas. Em outras palavras, se você remover uma linha após uma correspondência que também corresponda, provavelmente também deverá remover a linha que segue.É implementado de maneira simples - mas você precisa olhar um pouco para trás.
Ele funciona trocando espaços de espera e padrão para cada linha lida - para que a última linha possa ser comparada à corrente a cada vez. Portanto, quando
sed
lê uma linha, ela troca o conteúdo de seus buffers - e a linha anterior é o conteúdo de seu buffer de edição, enquanto a linha atual é colocada no espaço de espera.Portanto,
sed
verifica a linha anterior para uma correspondência ematch
, se!
não for encontrada, as duas expressões na{
função}
são executadas.sed
vaig
et o espaço hold, substituindo o espaço padrão - o que significa que a linha atual é, em seguida, em ambos os espaços de espera e padrão - e, em seguida, ele irá//
verificar se há uma correspondência para a sua expressão regular mais recentemente compilado -match
- e se ele não fazmatch
isso estáp
arrumado.Isso significa que uma linha só será impressa se não aparecer e a linha imediatamente anterior não . Também renuncia a quaisquer trocas desnecessárias para sequências de es.
match
match
match
Se você quisesse uma versão que pudesse eliminar um número arbitrário de linhas ocorrendo após uma
match
, seria necessário um pouco mais de trabalho:... substitua o 5 pelo número de linhas (incluindo a linha correspondente) que você deseja remover ...
fonte