
Tenho uma série muito longa de URLs sem caractere de separação, no mesmo formato abaixo:
http://example.comhttp://example.nethttp://example.orghttp://etc...
Quero que cada URL esteja em uma nova linha. Tentei fazer isso substituindo todas as instâncias de "http://" por "\nhttp://" usando sed
sed 's_http://_\nhttp://_g' urls.txt
mas ocorre uma falha de segmentação (violação de memória). Só posso supor que o tamanho do arquivo (mais de 100 GB) está fazendo com que o sed exceda algum limite.
Eu poderia dividir o arquivo em vários arquivos menores para processamento, mas todas as instâncias de "http://" precisariam ser mantidas intactas.
Existe uma maneira melhor de fazer isso?
Responder1
Com awk
você pode evitar a leitura de uma grande quantidade de texto de uma só vez:
awk -vRS='http://' -vORS='\nhttp://' 1 urls.txt > urlsperline.txt
O sucesso pode depender da awk
implementação utilizada. Por exemplo, gawk
funciona bem, mas mawk
trava.
Responder2
Isso fará o trabalho:
perl -pe 'BEGIN { $/ = "//" } s!(?=http://\z)!\n!' urls.txt
Definindo$/, mudei a definição de uma linha para que ela termine //
em vez de uma nova linha. Isso faz com que o Perl leia uma URL por vez. É improvável que um URL contenha //
exceto após o esquema, mas está tudo bem se isso acontecer, o regex impedirá que ele adicione novas linhas falsas.
Se quiser evitar adicionar uma linha em branco antes do primeiro URL:
perl -pe 'BEGIN { $/ = "//"; print scalar <> } s!(?=http://\z)!\n!' urls.txt
Você pode tentar fazer um benchmarking para ver se s!http://\z!\nhttp://!
é mais rápido. Eles são equivalentes. Observe que a /g
bandeira não é necessária na substituição, pois só pode haver uma correspondência por “linha”.
Responder3
- Altere todas as ocorrências de a
:
por uma nova linha, para dividir o arquivo. - Substituir
http
no final da linha com- uma nova linha seguida
http:
e anexe a próxima linha a ela
- Repita uma vez, para que as linhas pares e ímpares sejam atualizadas
Essas etapas são semelhantes a:
tr ':' '\n' | sed -e '/http$/{N;s/http\n/\nhttp:/}' | sed -e '/http$/{N;s/http\n/\nhttp:/}'
Verifique se há linhas que não começam com
http://
, imprima os números das linhas. Isso só ocorreria se : estivesse em algum lugar da URL que não fosse depois dehttp
.grep -nv '^http://'