Grep com mais de uma entrada. Como separa-las?

1. Grep com mais de uma entrada. Como separa-las?

Daniel Carvalho
dacarpe

(usa Linux Mint)

Enviado em 02/11/2016 - 14:28h

Olá a todos. Este é meu primeiro post.

Estou começando a estudar Shell Script por hobbie. Meu primeiro script de estudo tem sido um cadastro de protocolos de atendimento dessas centrais de telemarketing, mas pro consumidor. É algo que facilitaria minha vida pra guardar protocolos de atendimento.

O script completo se encontra aqui: https://github.com/dacarpe/protocolos-net/blob/master/protocolos.sh

Estou trabalkhando ele já com o YAD. To batendo cabeça mas tá sendo bacana pra estudar.

MINHA DÚVIDA

Quando o usuario escolhe procurar uma entrada cadastrada, ele digita um termo de busca e o script usa o grep pra acessar o arquivo de saida e buscar todas as entradas com o termo. No arquivo de saida uso o separador '|' pra delimitar os campos. Fica mais ou menos assim...

CENTRAL|DATA|ATENDENTE|PROTOCOLO|DESCRIÇÃO|
NET|01/11/2016|Armando|001|Atencioso o bastante para não me irritar|
NET|27/10/2016|Filipe|002|Meio nervoso. Fiquei puto.|
TIM|31/10/2016|Danilo|003|O cara não sabe atender.|


A primeira linha é o título dos campos.

Então, a linha que faz a busca e joga pro YAD exibir o resultado é a seguinte:

grep -i "$SEARCH" prot_reg.csv | tr -s '|' '\n' | yad --text-info --title="Resultado da Pesquisa" --text="Abaixo seguem os resultados encontrados" --width=500 --height=650 --button=gtk-ok:0 


Mas o resultado aparece só com o que foi digitado pelo usuário, e eu queria que a exibição contivesse os títulos dos campos antes de cada exibição, com uma linha vazia entre eles.
Então pensei na seguinte saída:


for VAR in $(seq 5)
do
head -1 prot_reg.csv | cut -d'|' -f"$VAR" >> saida.txt
grep "$PESQ" -i prot_reg.csv | cut -d'|' -f"$VAR" >> saida.txt
echo >> saida.txt
done


OBS: aqui o arquivo saida.txt é só pra teste. Queria jogar a saída pra uma caixa de TEXT_INFO do YAD.

Este loop só não funciona quando o grep acha de mais de uma entrada, porque ele joga o nome do campo só uma vez e em seguida joga as entradas separadinhas. Tipo assim:

CENTRAL
NET
NET

DATA
01/11/2016
27/10/2016

ATENDENTE
Armando
Filipe

PROTOCOLO
001
002

DESCRIÇÃO
Atencioso o bastante para não me irritar
Meio nervoso. Fiquei puto.


Alguém tem alguma ideia de como fazer pra ele fazer isso individualmente?


  


2. Re: Grep com mais de uma entrada. Como separa-las?

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 02/11/2016 - 15:31h

dacarpe escreveu:

Olá a todos. Este é meu primeiro post.

Estou começando a estudar Shell Script por hobbie. Meu primeiro script de estudo tem sido um cadastro de protocolos de atendimento dessas centrais de telemarketing, mas pro consumidor. É algo que facilitaria minha vida pra guardar protocolos de atendimento.

O script completo se encontra aqui: https://github.com/dacarpe/protocolos-net/blob/master/protocolos.sh

Estou trabalkhando ele já com o YAD. To batendo cabeça mas tá sendo bacana pra estudar.

MINHA DÚVIDA

Quando o usuario escolhe procurar uma entrada cadastrada, ele digita um termo de busca e o script usa o grep pra acessar o arquivo de saida e buscar todas as entradas com o termo. No arquivo de saida uso o separador '|' pra delimitar os campos. Fica mais ou menos assim...

CENTRAL|DATA|ATENDENTE|PROTOCOLO|DESCRIÇÃO|
NET|01/11/2016|Armando|001|Atencioso o bastante para não me irritar|
NET|27/10/2016|Filipe|002|Meio nervoso. Fiquei puto.|
TIM|31/10/2016|Danilo|003|O cara não sabe atender.|


A primeira linha é o título dos campos.

Então, a linha que faz a busca e joga pro YAD exibir o resultado é a seguinte:

grep -i "$SEARCH" prot_reg.csv | tr -s '|' '\n' | yad --text-info --title="Resultado da Pesquisa" --text="Abaixo seguem os resultados encontrados" --width=500 --height=650 --button=gtk-ok:0 


Mas o resultado aparece só com o que foi digitado pelo usuário, e eu queria que a exibição contivesse os títulos dos campos antes de cada exibição, com uma linha vazia entre eles.
Então pensei na seguinte saída:


for VAR in $(seq 5)
do
head -1 prot_reg.csv | cut -d'|' -f"$VAR" >> saida.txt
grep "$PESQ" -i prot_reg.csv | cut -d'|' -f"$VAR" >> saida.txt
echo >> saida.txt
done


OBS: aqui o arquivo saida.txt é só pra teste. Queria jogar a saída pra uma caixa de TEXT_INFO do YAD.

Este loop só não funciona quando o grep acha de mais de uma entrada, porque ele joga o nome do campo só uma vez e em seguida joga as entradas separadinhas. Tipo assim:

Alguém tem alguma ideia de como fazer pra ele fazer isso individualmente?


Boa tarde dacarpe.
Sim, tenho uma ideia . . . :)
Segue:
TTLO=(CENTRAL DATA ATENDENTE PROTOCOLO DESCRIÇÃO)
OLDIFS="$IFS"
line="NET|01/11/2016|Armando|001|Atencioso o bastante para não me irritar."
IFS="|" ; read -a FIELD <<< "$line"
IFS="$OLDIFS"
for ((x=0;x<5;x++));do
echo -e "${TTLO[$x]}: ${FIELD[$x]}\n"
done


Saida:
CENTRAL: NET

DATA: 01/11/2016

ATENDENTE: Armando

PROTOCOLO: 001

DESCRIÇÃO: Atencioso o bastante para não me irritar.

IMPRIMINDO a PARTIR de UM ARQUIVO:
TTLO=(CENTRAL DATA ATENDENTE PROTOCOLO DESCRIÇÃO)
OLDIFS="$IFS"
while IFS=$'\n' read -r line;do
IFS="|" ; read -a FIELD <<< "$line"
IFS="$OLDIFS"
for ((x=0;x<5;x++));do
echo -e "${TTLO[$x]}: ${FIELD[$x]}"
done;echo; done<CADASTRO.txt

#Saída:
CENTRAL: NET
DATA: 01/11/2016
ATENDENTE: Armando
PROTOCOLO: 001
DESCRIÇÃO: Atencioso o bastante para não me irritar

CENTRAL: NET
DATA: 27/10/2016
ATENDENTE: Filipe
PROTOCOLO: 002
DESCRIÇÃO: Meio nervoso. Fiquei puto.

CENTRAL: TIM
DATA: 31/10/2016
ATENDENTE: Danilo
PROTOCOLO: 003
DESCRIÇÃO: O cara não sabe atender.


É Isso . . .
IMPORTANTE: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -n '/^Educação/,/ajudou/p')\n" 


Att.:
Marcelo Oliver











3. Re: Grep com mais de uma entrada. Como separa-las?

Daniel Carvalho
dacarpe

(usa Linux Mint)

Enviado em 02/11/2016 - 16:11h

Oi Marcelo.

Valeu pela resposta.

Como disse, sou muito iniciante e esse é meu primeiro script. Então vou tentar entender aqui o que você propôs. Até porque vou ter que adaptar aqui pro uso do YAD. Vamos lá...

TTLO=(CENTRAL DATA ATENDENTE PROTOCOLO DESCRIÇÃO) 

Aqui voce criou uma array né? Você vai puxar cada uma delas ali no for né isso?

OLDIFS="$IFS" 

Aqui você só protegeu o conteúdo padrão da variável de ambiente IFS pra depois conseguir retornar ele no final.

while IFS=$'\n' read -r line;do 

Enquanto IFS for igual a ENTER receba o conteúdo da variável line

IFS="|" ; read -a FIELD <<< "$line" 

IFS agora delimita com '|'; receba o conteúdo da variável FIELD através do conteúdo da variável line

IFS="$OLDIFS" 

Retorne com o valor padrão de IFS

for ((x=0;x<5;x++));do
echo -e "${TTLO[$x]}: ${FIELD[$x]}"

Para x começando do 0 e não ultrapassando o 5, some 1 a cada loop e faça
Escreva (aceitando parametros) conteudo de TTLO correspondente ao array: conteúdo de FIELD correspondente ao campo

done;
echo;
done<CADASTRO.txt
done

Primeiro done fecha o for; echo pra dar o enter que foi mencionado no while lá em cima; segundo done pra fechar o while. Não tem um done a mais aí não? Que done é esse com o CADASTRO.TXT?

É isso?
Me confirma pra eu entender o que devo modificar pra adaptar ao script...


4. Re: Grep com mais de uma entrada. Como separa-las?

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 02/11/2016 - 18:20h

dacarpe escreveu:

Oi Marcelo.
Valeu pela resposta.
Como disse, sou muito iniciante e esse é meu primeiro script.
Então vou tentar entender aqui o que você propôs.
Até porque vou ter que adaptar aqui pro uso do YAD. Vamos lá...
.
.
.
É isso?
Me confirma pra eu entender o que devo modificar pra adaptar ao script...

==============================================
Boa tarde dacarpe.
Vamos aos questionamentos.

TTLO=(CENTRAL DATA ATENDENTE PROTOCOLO DESCRIÇÃO) 

Aqui voce criou uma array né? Você vai puxar cada uma delas ali no for né isso?
mso:Ok

OLDIFS="$IFS" 

Aqui você só protegeu o conteúdo padrão da variável de ambiente IFS pra depois conseguir retornar ele no final.
mso:Ok

while IFS=$'\n' read -r line;do 

Enquanto IFS for igual a ENTER receba o conteúdo da variável line
mso:Enquanto IFS for igual a NOVA LINHA receba o conteúdo da variável line
IFS=$'\n' É para LER a linha inteira como uma única VAR

IFS="|" ; read -a FIELD <<< "$line" 

IFS agora delimita com '|'; receba o conteúdo da variável FIELD através do conteúdo da variável line
mso: Altero o IFS, para o mesmo utilizado em "CADASTRO.txt".
É gerada a array "FIELD" com o conteúdo da variável line

IFS="$OLDIFS" 

Retorne com o valor padrão de IFS
mso:Ok

for ((x=0;x<5;x++));do
echo -e "${TTLO[$x]}: ${FIELD[$x]}"

Para x começando do 0 e não ultrapassando o 5, some 1 a cada loop e faça
Escreva (aceitando parametros) conteudo de TTLO correspondente ao array: conteúdo de FIELD correspondente ao campo
Escreva "${TTLO[$x]}: ${FIELD[$x]}", onde x varia de 0 a 4.
Temos:
05 Títulos, de ${TTLO[0] a ${TTLO[4]
e
5 CAMPOS em cada "line", de ${FIELD[0]} a ${FIELD[4]}

done;
echo;
done<CADASTRO.txt
done

Primeiro done fecha o for; echo pra dar o enter que foi mencionado no while lá em cima; segundo done pra fechar o while. Não tem um done a mais aí não? Que done é esse com o CADASTRO.TXT?
mso:ok Primeiro done fecha o for

mso: echo PULA UMA LINHA ENTRE OS REGISTROS

done<CADASTRO.TXT Fecha o "while" e indica que os dados serão pegos do ARQUIVO CADASTRO.TXT.

Não EXISTE esse 3º "done" no script.
TTLO=(CENTRAL DATA ATENDENTE PROTOCOLO DESCRIÇÃO)
OLDIFS="$IFS"
while IFS=$'\n' read -r line;do
IFS="|" ; read -a FIELD <<< "$line"
IFS="$OLDIFS"
for ((x=0;x<5;x++));do
echo -e "${TTLO[$x]}: ${FIELD[$x]}"
done;echo; done<CADASTRO.txt


Com o awk, é mais pratico.
awk -F"|" '{OFS="\n";print "CNTL: "$1,"DATA: "$2,"NOME: "$3,"PROT: "$4,"CMNT: "$5"\n"}' CADASTRO.txt 


cat CADASTRO.txt
NET|01/11/2016|Armando|001|Atencioso o bastante para não me irritar
NET|27/10/2016|Filipe|002|Meio nervoso. Fiquei puto.
TIM|31/10/2016|Danilo|003|O cara não sabe atender.


É isso....

E não ESQUEÇA:
Se a resposta foi ESCLARECEDORA, sanou suas dúvidas . . .
Marque o tópico como resolvido e a resposta como A MELHOR . . . :)

Att.:
Marcelo Oliver






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts