Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

1. Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Jorge Borges Gomes Junior
junao.zn

(usa Slackware)

Enviado em 15/09/2010 - 10:26h

Olá pessoal sou novo no grupo estou começando agora a desenvolver em shell script. Trabalho com arquivos de grande porte em txt e preciso fazer algumas substituições em um arquivo x com base no arquivo y.

Ex: Arquivo X - (IP#PAÍS#LAT#LONG)
111.222.333.57#BR#-10.1235#-10.5685
222.777.888.99#US#-2.3585#-2.6258
333.444.333.25#BR#-10.4552#-13.5225

Ex: Arquivo Y - (IP)
111.222.333.57
333.444.333.25
222.777.888.99
111.222.333.57
333.444.333.25

Bom esses são os meus arquivos sendo que o Arquivo X tem 4 milhões de linhas e o Arquivo Y tem 142 milhões.
Gostaria de saber como eu poderia fazer a substituição dos IPs no arquivo Y pela a informação completa do arquivo X?

Eu tentei utilizar:

bash_completa_ip.sh
$ for ip in `cat arquivo_y`
$ do
$ grep $ip arquvio_x >> arquiv_final_completo
$ done

Porém retornou o seguinte erro:
bash_completa_ip.sh: fork: cannot allocate memory
só que a minha máquina tem 24Gb de Ram e trabalho com um processador i7 980x.

Desde já agradeço pela ajuda de vcs


  


2. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Luis Henrique Gonçalves
ricklgoncalves

(usa Slackware)

Enviado em 15/09/2010 - 10:37h

Bom dia amigo,

Observando seu problema o que me veio na cabeça é utilização do while ao inves do for.
Ficaria assim:

bash_completa_ip.sh
$ while read line;
$ do
$ grep $line arquvio_x >> arquiv_final_completo
$ done < arquivo_y

Faça o teste e nos diga o que resultou.


3. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Jorge Borges Gomes Junior
junao.zn

(usa Slackware)

Enviado em 15/09/2010 - 10:42h

Olá amigo, eu já tentei fazer dessa maneira também, não resultou erro, porém está extremamente lento.

Muito obrigado pela tentativa, mas preciso de algum comando que faça isso em um tempo mais curto.



4. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Luis Henrique Gonçalves
ricklgoncalves

(usa Slackware)

Enviado em 15/09/2010 - 11:37h

Bem amigo, neste caso sinceramente não sei o que lhe sugerir.

Fiquei curioso pois isso seria bastante útil pra mim também, vou tentar pensar em alguma coisa, espero que o pessoal aqui do grupo possa ajudar também.


5. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 15/09/2010 - 12:00h

vixi cara, nunca vi esse erro

pode tentar algo como

------------------------------
VAR_Y=`more arquivo_y`
VAR_X=`more arquivo_x`

for ip in `echo $VAR_Y`; do
VAR_TUDO=`echo "$ip" | grep $VAR_X`
done

echo "$VAR_TUDO" > arquiv_final_completo
------------------------------

antes de alterar, verifica onde está pesando, creio que deve ser na hora de passar p arquivo, pois a velocidade do HD é muito mais lenta que do processador e memoria

debuga o script e ve onde é o problema

bash -xv bash_completa_ip.sh

ve tbm quanto tempo demora a execução

time ./bash_completa_ip.sh

depois faça isso com o novo script e compara se foi mais rapido ou não


6. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Jorge Borges Gomes Junior
junao.zn

(usa Slackware)

Enviado em 15/09/2010 - 16:28h

Olá Douglas, tentei fazer da maneira passada mas me resultou em um outro erro.

./bash_completa_ip.sh: xrealloc: subst.c:4952: cannot allocate 1073741824 bytes (6442692608 bytes allocated)

teria alguma outra maneira?

Mas muito obrigado pela dica isso me ajudará em outros processos que tenho por fazer.


7. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 15/09/2010 - 17:45h

vixi

é que tem muita informação nos arquivos, muita msm, coisa que o shell não deve aguentar, pelo menos não em variaveis

pelo visto vai ter que fazer alguma maneira sem usar variaveis, tenta o modo que o rick falou e faz alguns testes

ver onde está pesando, vai ter que debuga
bash -xv bash_completa_ip.sh

ver quanto tempo demora
time ./bash_completa_ip.sh

se o atrazo for o HD, ai não tem jeito, só colocando hd SSD ou fazendo raid, e msm assim não posso garantir que a diferença possa ser notada, mas melhorar uns 20%, ai pode ser que aconteça

se for mecher com variaveis, ai pode ser que linguagem de programação aceite

eu só sei Shell e Python, pode ser que python consiga, mas não é certeza, isso é de ultimo caso

o erro aparece quando inicia o script ou no meio da execução


8. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Jefferson Diego
Diede

(usa Debian)

Enviado em 16/09/2010 - 01:01h

Tente assim:

#! /bin/bash
cat arquivo_x| while read linha_x; do
IP=$(echo $linha_x| cut -d '#' -f 1)
sed -i "s/$IP/$linha_x/g" arquivo_y
done


Só salvar e chamar por "bash ./arquivo_salvo".


9. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Marcos Paulo Ferreira
Daemonio

(usa Slackware)

Enviado em 17/09/2010 - 00:47h

Difícil.. enquanto a lógica for: Para cada linha do arquivo X, procure-a no arquivo Y, o script fará um número absurdo de comparações.
Ou seja: Só nessa brincadeira você irá ter feito 4*124 milhões de comparações, que é um pouco maior que "coisa pra caramba". :|

Acho que um script que faça essa tarefa em um tempo mais curto que o do ricklgoncalves seja quase impossível (pelo menos em se tratando de shell script). Afinal, até agora só o script dele funcionou, como você disse.

Um jeito de melhorar esse tempo de pesquisa, seria você dividir esse arquivo Y em vários outros seguindo algum padrão (ex: cada arquivo contém um determinado país, ou uma parte específica do ip, etc).
Desse modo as comparações seriam estrondozamente menores, pois cada linha em X saberia onde procurar em Y. Lógico que você gastaria tempo para separar o arquivo Y em outros menores, mas pelo menos você ganharia tempo em cada pesquisa que você fizesse.

Tipo, vendo a mensagem de erro que você postou:

xrealloc: subst.c:4952: cannot allocate 1073741824 bytes (6442692608 bytes allocated)

parece que o bash impõe algum limite no tamanho do buffer a ser alocado. Seria interessante, você pegar o código fonte do bash ou desse subst.c (ou do grep, nem sei te falar o certo :( ) e aumentar o tamanho do buffer diretamente no source. Nunca fiz isso e nem sei se funciona, mas fica a dica.

Acho que é isso.
t+


10. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 17/09/2010 - 08:34h

pods cre, aumentar o limite de buffer xD

afinal é open-source e é uma enorme vantagem nesses casos, separar o arquivo Y é uma boa tbm

ou então como eu disse, usar uma linguagem de programação

o processador é bom e a quantidade de memoria está perfeita p processador, a lentidão é o HD, melhorar a parte fisica pode melhorar, mas ai ja está se tratando de investimento e isso é com vc, mas fazer raid ou melhorar se ja estiver, pode ser uma boa, nunca fiz raid, mas sei +- como funciona

======================

agr surgiu uma duvida, nesse loop ele faz o seguinte

lê, filtra, grava
lê, filtra, grava
lê, filtra, grava
lê, filtra, grava

agr se ler tudo que tiver que ler e armazenar na memoria, filtrar tudo que tiver que filtrar e dpois gravar tudo que tiver que gravar, isso ajuda no desempenho??

tem risco de dar gargalo na memória msm com 24GB??


11. Re: Substituir strings em arquivo txt dinamicamente. [RESOLVIDO]

Jorge Borges Gomes Junior
junao.zn

(usa Slackware)

Enviado em 21/09/2010 - 13:59h

Olá Colegas, muito obrigado pelas dicas!
Eu sou novo em programação shell e em linux, tentei utilizar as formas passadas mas o arquivo é muito grande e não estava sendo viável, tentei o que o Diede fez mas acabou resultando na mesma fica muito demorado.

A maneira que eu encontrei foi fazendo um teste de importar esses arquivos para o mysql no hd raid e não é que rolou!

O arquivo de ip de 4 milhões fez em 3 minutos a importação e o outro dos dados com 142 milhões fez em 15 minutos depois fiz um relacionamento e mandei escrever o select em um arquivo txt e ficou beleza. O select demorou uma meia hora e no total não levei mais de 1 hora.

Obrigado pela ajuda de todos e segue a dica caso alguem precise fazer algo desse tipo.

Abrax






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts