Eu tenho arquivos que foram gerados por um programa que não colocou novas linhas no final dos registros. Quero colocar novas linhas entre os registros e posso fazê-lo com um simples script sed:
sed -e 's/}{/}\n{/g'
O problema é que os arquivos de entrada têm vários gigabytes de tamanho e, portanto, as linhas de entrada para sed têm vários GBs de comprimento. sed tenta manter uma linha na memória, o que não funciona nesse caso. Tentei a --unbuffered
opção, mas isso pareceu torná-la mais lenta e não permitiu que ela terminasse corretamente.
tr
a traduzir}
em\n
e, em seguida, usarsed
para adicionar um}
no final de cada linha? Assim:tr '}' '\n' < your_file.txt| sed 's/$/}/'
printf "\n" >> file
}{
repetido até que vários gigabytes sejam suficientes.dd if=file cbs=80 conv=unblock
faria - mas raramente é tão simples assim.Respostas:
Você pode usar outra ferramenta que permite definir o separador de registros de entrada. Por exemplo
Perl
A variável especial
$/
é o separador de registros de entrada. Configurá-lo para}{
definir linhas como terminando em}{
. Dessa forma, você pode conseguir o que deseja sem ler a coisa toda na memória.mawk ou gawk
Essa é a mesma ideia.
RS="}{"
define o separador de registro para}{
e, em seguida, você imprime}
uma nova linha{
(exceto o primeiro registro) e o registro atual.fonte
Perl para o resgate:
A configuração
$/
para\1024
lerá o arquivo em pedaços de 1024 bytes. A$closing
variável lida com o caso quando um pedaço termina}
e o próximo começa com{
.fonte
Você deveria fazer:
Provavelmente é a solução mais eficiente.
Isso coloca um
{}
para proteger todos os possíveis dados finais. Com mais umtr
processo, você pode trocá-lo e fazer uma linha em branco no início do primeiro{
campo. Gostar...Portanto, o primeiro, com dados de exemplo de don, faz:
... e o segundo faz ...
Não há nova linha final no segundo exemplo - embora exista uma no primeiro.
fonte
Um
sed
utilitário tipo binário chamadobbe
Acho mais fácil permanecer com a sintaxe semelhante a sed neste caso.
I muito preferem usar o
bbe
utilitário (disponível através do seu {uni, Linu} instalação do pacote de x, eqapt-get
). Ou aqui, se você faz parte da galera do idiota, apesar de eu não ter pessoalmente verificado esse link em particular.1. Suporta o
s/before/after/
idiomaÉ um "Editor de Blocos Binários", que suporta operações semelhantes a sed (entre outras). Isso inclui o
s/before/after/
idioma de substituição super comum que você precisa. Observe que, como não existem linhas em si dobbe
ponto de vista, não há "g global" no final do comando.Como um teste rápido (observe o necessário
-e
):produz:
2. No seu caso específico
}{
da}\n{
conversãoPortanto, se tivéssemos um arquivo enorme preenchido com um milhão de números no formato (digamos)
{1}{2}{3}
...{1000000}
sem retorno de carro, poderíamos trocá}{
-lo}\n{
facilmente e ter todos os números um por linha.Isso seria com este
bbe
comando:Conforme testado neste loop zsh, do qual pegamos apenas o final:
O que produziria isso:
(sem retorno de carro à direita, é claro.)
fonte