Eu sei que espremer várias linhas em branco pode ser feito usando cat -s
(e espremer todas as linhas em branco pode ser feito usando tr -s '\n'
), mas estou curioso para pesquisar essa condição em um fluxo de entrada.
Achei que stream-of-input | grep -qz $'\n\n\n'
ia dar certo, mas não dá.
Existe uma maneira de fazer essa pesquisa com ferramentas simples?
Em outras palavras, leia a entrada e saia com um status zero se três bytes consecutivos forem caracteres de nova linha ou saia com um status diferente de zero se o EOF for atingido sem encontrar três caracteres de nova linha consecutivos.
Você pode usar
tr
para transformar o fluxo em um que você pode grep normalmente:Isso transforma todos os
x
bytes em bytes nulos e todos os bytes de alimentação de linha emx
s, que podem ser agrupados como de costume. Ou seja, ele se move um passo ao longo do caminho linefeed -> x -> null, então uma sequência de três linefeeds agora será uma sequência de trêsx
s, e nenhum outrox
byte ocorrerá (eles se tornarão nulos terminando linhas para ogrep
) .Isso funciona com POSIX
tr
, masgrep -z
é uma extensão. Você pode não precisar dele - o comportamento de separação não é necessário aqui - e a maioria dosgrep
s lidará com dados binários, mas o POSIXgrep
só é necessário para trabalhar em arquivos de texto, então você dependerá de uma extensão de uma forma ou de outra.Se seus dados reais são um arquivo de texto, ou simplesmente não dependem de um comportamento binário seguro, você provavelmente pode sobreviver com apenas
- ou seja, apenas trocando os dois bytes. Isso é quase compatível com POSIX, mas provavelmente funcionará na prática em qualquer lugar (o problema é que a linha final não será terminada corretamente, portanto, não é um arquivo de texto, portanto,
grep
não é estritamente necessário aceitá-lo ).Um possível problema em ambos os casos é que um arquivo sem
x
bytes existentes será considerado como uma linha muito longa, que pode exceder os limites que suagrep
implementação manipulará. Escolher outro byte esperado para ser comum pode contornar isso.Fiquei surpreso que seu
grep -qz $'\n\n\n'
comando original não funcionou, mas tinha um problema de falso- positivo para mim - parecia se comportar comogrep -qz ''
e sempre correspondia. Eu não tenho certeza por que isso é.lex
(ouflex
) poderia lidar com isso, por exemplo, o seguinte salvo no arquivotresn.l
com as regras extras principalmente para evitar que a saída padrão seja stdout (você pode querer isso?)compila com
make
regras implícitas mais a extração delibfl*
em alguns sistemas você pode precisar adicionar
-L/opt/local/lib
ou algo assimCFLAGS
ou tambémLDFLAGS
selibfl*
estiver escondido em algumas portas ou sistema de pacotes fora do espaço de compilação do fornecedor.