Como eu misturaria padrões e intervalos numéricos no sed (ou qualquer ferramenta semelhante - awk por exemplo)? O que eu quero fazer é combinar certas linhas em um arquivo e excluir as próximas n linhas antes de continuar, e eu quero fazer isso como parte de um pipeline.
105
+N
padrão é uma extensão GNU. Mude o primeiron
para umN
em seu segundo exemplo para fazê-lo incluir a linha com o padrão./pattern/,+5
define um intervalo, que começa com uma linha contendo "padrão" (/pattern/
) e termina 5 linhas depois (+5
). O último caractered
é um comando a ser executado em cada linha desse intervalo, que é "excluir". Na segunda receita, em vez de combinar um intervalo, ele corresponde apenas à linha que contém o padrão (/pattern/
) e, em seguida, executa uma série de comandos{n;N;N;N;N;d}
:, que basicamente imprime a próxima linha (n
) e então lê e finalmente descarta as próximas 4 linhas (N;N;N;N;d
)sed -e '/pattern/{n;N;N;N;N;d;}' file.txt
something
faça :,sed -E '/^something$/,$d'
onde-E
é o regex estendido de portabilidade POSIX.Sem extensões GNU (por exemplo, no macOS):
Para excluir 5 linhas após um padrão (incluindo a linha com o padrão)
Adicione
-i ''
para editar no local.fonte
awk
Soluções simples :Suponha que a expressão regular a ser usada para encontrar linhas correspondentes seja armazenada na variável shell
$regex
e a contagem de linhas a serem puladas$count
.Se a linha correspondente também deve ser ignorada (as
$count + 1
linhas são ignoradas):Se a linha correspondente deveria não ser pulada (
$count
linhas após a correspondência são puladas):Explicação:
-v regex="$regex" -v count="$count"
defineawk
variáveis com base em variáveis de shell de mesmo nome.$0 ~ regex
corresponde à linha de interesse{ skip=count; next }
inicializa a contagem de pulados e prossegue para a próxima linha, pulando efetivamente a linha correspondente; na 2ª solução, oprint
antesnext
garante que é não ignorado.--skip >= 0
diminui a contagem de saltos e executa uma ação se (ainda)> = 0, o que implica que a linha em questão deve ser saltada.{ next }
prossegue para a próxima linha, efetivamente pulando a linha atual1
é uma abreviação comumente usada para{ print }
; ou seja, a linha atual é simplesmente impressa1
é equivalente a{ print }
é que1
é interpretado como um padrão booleano que por definição sempre avalia como verdadeiro, o que significa que sua ação associada (bloco) é executada incondicionalmente. Como não há nenhuma ação associada neste caso, oawk
padrão é imprimir a linha.fonte
Isso pode funcionar para você:
fonte
pattern_number.txt
é um arquivo de 2 colunas contendo o padrão a ser correspondido na 1ª coluna e na 2ª o número de linhas a pular. O primeirosed
comando transforma o arquivo em umsed
script que executa a correspondência e o salto correspondentes; esse script é fornecido via-f
e stdin (-
) para o segundosed
comando. O segundosed
comando opera em um arquivo de entrada ad-hoc de amostra formado a partir da saída deseq 21
para demonstrar que funciona.Usando Perl
fonte
Esta solução permite que você passe "n" como parâmetro e ele lerá seus padrões de um arquivo:
O arquivo chamado "-" significa stdin para awk, então ele é adequado para o seu pipeline
fonte