|
From: | Julio C. Neves |
Subject: | Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto |
Date: | Wed, 24 Dec 2014 14:07:00 -0200 |
A vivencia nesse ambiente me mostrou que em se falando de big file, as respostas eficientes são sed e awk
On 24-12-2014 11:03, 'Julio C. Neves' address@hidden [shell-script] wrote:
Ola Júlio,Fala Mercês,
vens para o RJ passar o fim de ano? Se vier um (mentira, diversos) chope te espera...
Cara vc já tentou usar a opção -f do grep ou do sed? São super otimizadas.
Um pouco de teoria (da 10aª edição do meu livro que finalmente deve ser lançada em Janeiro)
=======================================
A opção -f
Vamos pegar um pedaço de /etc/passwd e colocá-lo no arquivo passwd.tmp:
$ tail -7 /etc/passwd > passwd.tmp
Veja como ele ficou (os que terminam em reticências foram cortados porque são dados que não interessam ao caso e para não haver quebra de linha que prejudicaria a legibilidade):
$ cat passwd.tmp
bin:x:2:2:bin:/bin:/bin/sh
pulse:x:109:114:PulseAudio daemon,,,:/var/run/pulse:...
rtkit:x:110:117:RealtimeKit,,,:/proc:/bin/false
saned:x:111:118::/home/saned:/bin/false
hplip:x:112:7:HPLIP system user,,,:/var/run/hplip:...
gdm:x:113:120:Gnome Display Manager:/var/lib/gdm:...
julio:x:1000:1000:Julio Neves,,,:/home/julio:/bin/bash
postfix:x:114:123::/var/spool/postfix:/bin/false
Tenho um outro arquivo com logins names que desejo excluir de passwd.tmp.
$ cat exclui
postfix
hplip
gdm
bin
pulse
Eu posso, usando a opção -f ARQUIVO do sed, excluir direto de passwd.tmp os registros dos usuários indicados em exclui, mas antes preciso prepará-lo para que ele, que agora só tem os nomes dos usuários, passe a ter o comando de deleção do sed, no formato:
/^USUARIO:/d
Onde as barras (/) e o d formam a sintaxe do comando e o circunflexo (Expressão Regular que indica inicio de linha) e os dois pontos (:) marcam os limites da palavra. Se esses limites não fossem estipulados, todos os registros de passwd.tmp que contivessem, por exemplo, a palavra bin - mesmo como parte de outra maior - seriam deletados).
Preparando exclui:
$ sed -i 's|^|/^|;s|$|:/d|' exclui
$ cat exclui
/^postfix:/d
/^hplip:/d
/^gdm:/d
/^bin:/d
/^pulse:/d
Como você notou, usamos a barra vertical (|) como delimitador e o ponto e vírgula (;) serviu para usarmos dois comandos substitute (s) dentro do mesmo sed.
Observação: A explicação para o uso do ponto e vírgula (;), está na seção a seguir.
Agora que todos os comandos já estão montados, podemos proceder à deleção. Veja como:
$ sed -i -f exclui passwd.tmp
$ cat passwd.tmp
rtkit:x:110:117:RealtimeKit,,,:/proc:/bin/false
saned:x:111:118::/home/saned:/bin/false
julio:x:1000:1000:Julio Neves,,,:/home/julio:/bin/bash
Isto é a opção -f informou o nome do arquivo de comandos para o sed (exclui) utilizar e em seguida, informamos o arquivo a ser alterado (passwd.tmp). Como usamos a opção -i, as alterações foram feitas diretamente no último.
=======================================
Mas no teu caso, que é praticamente idêntico, podemos fazer assim:
Vamos preparar cada linha do arquivo para listar todos os registros que forem encontrados em $outfile. Para isso vamos preceder cada nome com um /^ e sucedê-los com um :/p. Digamos que um registro seja aaaa, ao fim da execução de:
$ sed -i 's|^|/^|;s|$|:/p|' $outfile
Ele ficará /^aaaa:/p, que seria o cmd do sed para imprimir. Então vamos listar os que já existem:
$ sed -n -f $outfile /etc/passwd | xargs -I{} echo o registro {} já existe
Se vc caprichar, põe tudo em um sed somente.
Em 23 de dezembro de 2014 23:36, Fernando Mercês address@hidden [shell-script] <address@hidden> escreveu:
Amigos,
Num script que acabei de fazer [1] tenho um arquivo de texto que é uma lista de nomes de usuário (um por linha). E quero checar se eles existem no sistema. Fiz deste jeito:
while IFS= read i; dogrep -qm1 "^$i:" /etc/passwd && echo "$i matches with an existent user. Be careful!"done < "$outfile"
Mas este "$outfile" é muito grande. Milhares de linhas e demora um pouco. Alguma ideia pra otimizar?
Grato e feliz natal! :)
[1] https://gist.github.com/merces/0a4d2272d79d00cc0fe1
Att,
Fernando Mercês
Linux Registered User #432779
www.mentebinaria.com.br
------------------------------------
"Ninguém pode ser escravo de sua identidade; quando surge uma possibilidade de mudança é preciso mudar". (Elliot Gould)
Veja se essa solução ficaria ineficiente, acho que fica uma solução bem "legível"
Supondo que o tal arquivo outfile não estivesse sorteado faria:
usuarios=$(gawk 'comando="sort | uniq" {print $1 | comando }' outfile) && echo $usuarios
com isso se teria uma lista sorteada e única de todos os usuários a serem verificados no sistema, e depois:
for usuario in $usuarios; do gawk -F: -v usuario=${usuario} '$0 ~ usuario { print "Achou usuário:"$1 }' /etc/passwd; done
então se lista todas as entradas de outfile que exista no sistema.
Isso é muito ineficiente?
Abraço e muitos chops no natal !!!
Luiz A Monteiro
[Prev in Thread] Current Thread [Next in Thread]
- Desempenho ao checar se string existe em arquivo de texto, Fernando Mercês, 2014/12/23
- Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto, Paulo Bettega, 2014/12/23
- Re: [Bulk] Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto, Sidney Souza, 2014/12/24
- Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto, Luis Fernando, 2014/12/24
- Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto, Julio C. Neves, 2014/12/24
- Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto, Luiz Alberto, 2014/12/24
- Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto, Julio C. Neves <=
- Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto, Ronaldo Ferreira de Lima, 2014/12/24
- Prev by Date: Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto
- Next by Date: Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto
- Previous by thread: Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto
- Next by thread: Re: [shell-script] Desempenho ao checar se string existe em arquivo de texto
- Index(es):