Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

1. Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Luiz Carlos
luizcarlos18rj

(usa Suse)

Enviado em 03/11/2014 - 16:04h

Oi galera, gostaria de saber se isso é possível...

Sou iniciante no shellscript ( iniciante mesmo, assim tipo noob )e tenho na minha rede um arquivo de um relógio de ponto (ponto.txt ) que todos os dias ele gera trechos como esse:

.
.
.
010000000000400694141103073107
020000000000455561141103073107
010000000007985619141103073328
.
.
.
Vou usar como ex. a primeira linha: "010000000000400694141103073107" e para fins de demosntração vou separálo em 4 partes:

010000000000 --- 0400694---141103---073107, onde:

"010000000000" ( gerado pelo sistema )

"0400694" ( número de matrícula do funcionário )

"141103" ( data-hora no formato aa/mm/dd )

"073107" ( hora entrada "07:31:07 am" )

Com isso em mãos eu queria criar um arquivo de texto com o cadastro da matrícula só das pessoas do meu setor que ia ficar + ou menos assim:

0400694 - Fulano da Silva
9928525 - Ciclano de Souza
8355974 - Beltrano Oliveira

( matriculas.txt)

Agora com esse arquivo em mãos tem como fazer um script que pega essas matrículas do arquivo matriculas.txt e localize (tipo com grep) no arquivo ponto.txt e me mostre resultados como esses?


010000000000400694141103073107 - Fulano da Silva - presente
020000000009928525141103083107 - Ciclano de Souza - Atrasado ( hora: 08:31:07 )
010000000007985619141103073328 - Beltrano Oliveira - Faltou ( registro não encontrado )

Meu real objetivo era localizar essas sequencias de matriculas num arquivo com dezenas de linhas e ver pelas ocorrencias se essas pessoas tão presenets, se chegaram atrasadas ( hora critério: 08:00 ) e e não localizou, lançar como falta, o objetivo disso é para o controle de presença.

Tem como criar um script assim? Como? ( partindo do zero )

Desde já agradeço...


Luiz Carlos







  


2. Re: Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 04/11/2014 - 09:12h

Tem como fazer, sim.

No entanto, eu recomendo não usar shell script para isso. Trabalhe com uma linguagem com funções melhores e mais eficientes de manipulação de texto, como Perl ou Python.


3. Re: Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Raimundo Alves Portela
rai3mb

(usa Outra)

Enviado em 04/11/2014 - 10:05h

Levando em consideração que o arquivo é de posição fixa, vc poderia usar isso a seu favor segue um esboço:


while read LINHA
do
MATRICULA=${LINHA:12:6} # posicao exata da matricula
if egrep -wq $MATRICULA ARQUIVO_COM_MATRICULAS_A_VALIDAR; then
echo "achou registro do usuario $MATRICULA" # adaptar para a sua necessidade
fi
done < ARQUIVO_DO_REGISTRO_DO_PONTO



4. Re: Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Pedro Henrique Rissato
pedrorissato

(usa Fedora)

Enviado em 04/11/2014 - 14:40h

Ta na mao...
Nao deixei totalmente pronto, pois esta com problema nos ausentes. Nao sei pq a variavel expr2 perde no valor no else do if principal... mas testei aqui e faz oque voce quer até o momento...

testa ai e me diz.... se alguém tiver lendo e souber responder da variável expr2 perder o valor no final me fala.... pq jah olhei e reolhei isso.


Ele não pesquisa arquivos que tenham 2 vezes a mesma matricula. Se tiver, ele ira mostrar somente o 1 registro. Estou supondo que seu arquivo de ponto esta separado por dia.... Por isso eu coloquei pra vc digitar o nome do arquivo de ponto.... o nome do arquivo de matricula eh o mesmo... os 3 (ponto, matricula e script) tem que estar no mesmo diretorio pra funcionar.... se nao for isso me avisa eu penso em algo..

PS.: NO ARQUIVO DE MATRICULA EU FIZ ASSIM!

0400694 JOSE DA SILVA
0455561 JOAO DA SILVA
7985619 JOSE JOAO DA SILVA
1234567 ZUEIRA
8765432 FALTOLINO

MATRICULA (1 tab) NOME

Está programado pra trabalhar assim na hora de buscar o nome! Deixe no mesmo formato xD

Ps2.: Os faltosos estão funcionando. O código ta certo. Eu que no arquivo de matricula dei ESPAÇO entre a matricula e o nome. Após dar TAB funcionou sem alterações!

Abraços xD

#!/bin/sh

echo 'Informe o nome completo do arquivo de ponto. Inclusive com extensao, se existir'
echo -ne 'Nome: '
read nponto

# Descobre e guarda quantas matrículas existem (Quantidade apenas)

qtdmat=$(cat matricula.txt | cut -c1-7 | wc -l)

# Pesquisa as matriculas no ponto (núcleo do script)

for ((i=1;i<=$qtdmat;++i))
do
var1=$(sed -n "$i"p matricula.txt | cut -c1-7)

expr1=$(cat $nponto | grep $var1)
expr2=$(cat matricula.txt | grep $var1 | cut -f2 -s)

if [[ ! -z $expr1 ]]
then
expr4hr=$(echo $expr1 | cut -c25-26)
expr4min=$(echo $expr1 | cut -c27-28)
expr4seg=$(echo $expr1 | cut -c29-30)

if [ $expr4hr -ge '08' ]
then

if [ $expr4min -ne '00' ]
then
expr3="Atrasado"
echo $expr1 '-' $expr2 '-' $expr3 '(' 'hora:' $expr4hr':'$expr4min':'$expr4seg ')'
fi

elif [[ $expr4hr < '08' ]]
then

expr3="Presente"
echo $expr1 '-' $expr2 '-' $expr3

fi

else

expr3="Ausente. Registro não encontrado."

echo $expr3 '-' $expr2

fi
done



5. Re: Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 04/11/2014 - 18:24h

Uma dúvida: esse relógio de ponto não registra saída? Olhando no exemplo inicial, eu imaginei que o primeiro campo teria valores que sugerem a direção do movimento do funcionário (por exemplo: 0100000000 é entrada, e 0200000000 é saída).

O script que foi mostrado acima (pelo pedrorissato) assumiria que o funcionário está presente se ele chegar às 07:59 e sair às 08:00. Acho que isso não está certo.

Aliás o mesmo script serve muito bem de exemplo de porquê de eu ter dito que recomendava não fazer uma aplicação como essa com script em shell. Além de o shell ser muito lento, ele, na verdade, faz muito pouco por conta própria, e depende de comandos externos para quase tudo -- até para testar condições de um mero if. Cada comando desses é um novo processo criado, com execução de comando externo, aguardo do retorno do tal comando externo, interpretação do resultado de tal comando externo e cancelamento do processo filho. Isso é lento. Mas pior do que isso é ter, como foi literalmente disposto, um laço de repetição com duas invocações ao grep sobre o conteúdo _integral_ de dois arquivos diferentes em cada iteração desse laço. Um verdadeiro absurdo computacional.

O outro script (do rai3mb) é só uma ideia, não trazendo o programa todo, e usa um pouco dos recursos que existem no Korn Shell e no bash em seu favor. Mas tais recursos só existem no KSH e no bash, não no shell padrão. Acho importante deixar isso bem claro pois, ainda que no Red Hat e derivados o /bin/sh seja um link para o bash, não o é no Debian e derivados (Ubuntu, Mint etc.), e aquela sintaxe de “${nome_variavel:posição_inicial:comprimento}” simplesmente não existe, e daria erro de sintaxe.

Como eu faria:

1) Faria um cache com o conteúdo do arquivo de matrículas, tendo a associação ao nome de cada usuário (array associativo).

2) Leria, uma única vez, o arquivo de registro de ponto, guardando a hora da última entrada de cada matrícula num outro array associativo, ou apagando o registro, caso o movimento fosse de saída.

3) Para cada data/hora de interesse, compararia os registros de cada chave do array matrícula-nome com a existência ou não e o eventual valor do registro correspondente no array matrícula-entrada, decidindo, então, entre a presença, atraso e ausência.

Dá para fazer desse jeito com o bash ou Korn Shell, que possuem arrays associativos (mas não com o shell tradicional, que não os possui). No entanto, reforço que eles são muito lentos em operações de strings e com os próprios arrays. Por isso mesmo, eu disse lá no começo que usaria um script em Perl ou Python. AWK também é uma possibilidade (i.e. um script totalmente escrito em AWK, não meras invocações a partir do shell), mas não tenho familiaridade suficiente com a linguagem para saber como seria o tratamento de mais de um arquivo de entrada de dados dentro do mesmo script.


6. Re: Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Pedro Henrique Rissato
pedrorissato

(usa Fedora)

Enviado em 04/11/2014 - 23:58h

Paulo... entendo suas preocupações. Também aprendi da mesma forma em Engenharia da Computação. Gasto computacional realmente é uma vital em determinadas áreas.

Contudo, continuo utilizando a regra “cada caso um caso”. O que ele precisa é um simples script de análise de informações básicas, ainda que envolva o uso de strings.

Realmente fiquei preocupado com o gasto computacional, e por isso coloquei à prova o script.

Criei um arquivo com 5.000 registros, como se fosse uma empresa com 5.000 funcionários. Não sei o tamanho da empresa que ele trabalha, mas trabalho em uma com 6.000 funcionários e o mesmo script serviria bem. Também gerei um arquivo de matrículas com os mesmos 5.000 funcionários, para ter certeza que o script entraria no if interno.

Monitorei o tempo de execução do script desde antes da entrada no laço for até sua finalização.
Utilizei meu noteebok particular um i7-4700MQ a 2.4Ghz.

Esta foi a saída após a execução de todas as análises:

04/11/2014 23:34:31 Iniciando programa
04/11/2014 23:35:11 Parando o programa

Total.: 40 segundos.

O load chegou a 35% da capacidade do processador.

Não fiz o teste para verificar os outros 2 ifs em relação aos funcionários “atrasadinhos”, mas ainda que todos estes 5.000 estivessem atrasados e dobrassem o tempo transcorrido (para 80 segundos) dependendo de quando ele precisa entregar isso, ainda acho viável.

Como disse, entendo sua preocupação, e não discordo de você, dependendo do ambiente que ele possui o script pode não ter tanta valia, mas pelo tempo de execução, na minha opinião cumpre seu papel.

Em relação à ter dados não únicos no arquivo de ponto, o script não serviria. Teria que adicionar um outro laço para tratar isto, mas pelo que ele deu a entender, pelo exemplo postado, ele verifica diariamente essas pessoas e apenas com o horário de entrada delas... Mas caso precise, estaremos por aqui.

Abraços.

Abaixo segue o link para download dos arquivos que fiz o teste:

http://we.tl/h6figpajZj


7. Re: Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 05/11/2014 - 12:25h

pedrorissato escreveu:

Paulo... entendo suas preocupações. Também aprendi da mesma forma em Engenharia da Computação. Gasto computacional realmente é uma vital em determinadas áreas.

Contudo, continuo utilizando a regra “cada caso um caso”. O que ele precisa é um simples script de análise de informações básicas, ainda que envolva o uso de strings.


Concordo com você. Mas isso não invalida o que eu disse.

Note que eu fui o primeiro a dizer que dava para fazer com shell, mas que, mesmo assim, não recomendava que o fizesse, sugerindo, em lugar disso, outras duas ferramentas com recursos mais adequados justamente à tarefa que foi proposta.

Na minha primeira postagem, eu não entrei no mérito da eficiência. Eu sugeri Perl e Python porque acredito que é realmente mais simples e mais fácil resolver o problema numa dessas linguagens do que com shell. Na verdade, uma delas (Perl) foi pensada justamente como uma linguagem para extração de dados e geração de relatórios, que é justamente o que ele quer fazer.

Realmente fiquei preocupado com o gasto computacional, e por isso coloquei à prova o script.

Criei um arquivo com 5.000 registros, como se fosse uma empresa com 5.000 funcionários. Não sei o tamanho da empresa que ele trabalha, mas trabalho em uma com 6.000 funcionários e o mesmo script serviria bem. Também gerei um arquivo de matrículas com os mesmos 5.000 funcionários, para ter certeza que o script entraria no if interno.

Monitorei o tempo de execução do script desde antes da entrada no laço for até sua finalização.
Utilizei meu noteebok particular um i7-4700MQ a 2.4Ghz.

Esta foi a saída após a execução de todas as análises:

04/11/2014 23:34:31 Iniciando programa
04/11/2014 23:35:11 Parando o programa

Total.: 40 segundos.

O load chegou a 35% da capacidade do processador.


Eu coloquei o aspecto da eficiência somente depois de ver o seu programa, que você postou depois da minha primeira intervenção.

Eu acredito que programar uma arte. Não no sentido estético, mas no sentido de que é uma atividade que depende de criatividade é que pode ser aprimorada com o uso de ferramentas e de técnicas cada vez melhores. E tais ferramentas e técnicas melhoradas e melhoráveis não são aplicáveis somente num supersistema gigantesco, mas mesmo no scriptzinho bobinho de cada dia. É preciso usá-las para aprimorá-las e aprimorarmo-nos com elas. Sem uso, enferrujamos.

Voltando um pouco do mundo ideal para o mundo real, mas sem esquecer dos ideais ao alcance das mãos, dá para dizer que, mesmo usando o bash, você poderia ter escrito seu script de modo mais eficiente, sem complicar muito a sintaxe. Aliás, possivelmente ficaria com uma sintaxe mais limpa em alguns trechos. Só como exemplo: ao passar o olho pela primeira vez, eu achei que você lia duas vezes (com grep) a totalidade dos arquivos dentro do loop. Só que são três vezes, e não duas: as duas com grep e mais uma com sed (e nas três você descarta quase todo o conteúdo lido!). Talvez isso ficasse mais visível com um código um pouco mais claro.

O seu programa, executando com os seus dados, rodou, na minha máquina, que é pior do que a sua, assim:

$ time bash localiza.sh ponto.txt > /tmp/output.txt

real 1m24.330s
user 0m3.180s
sys 0m4.896s


84,33 segundos, e isso sem estar completo e sem testar algumas partes.

Sem me basear no seu código, eu escrevi em pouco mais de cinco minutos o seguinte script em Perl:

#!/bin/perl

$REFERENCE_TIME=8*3600;

# Faz cache de informações dos funcionários.
if(open(EMPLOYEES, "<", "matricula.txt")){
while(<EMPLOYEES>){
chomp;
($reg, $name)=split(/\s+/, $_, 2);
$reg_name{$reg}=$name;
}
close(EMPLOYEES);
}

if(open(MOVEMENT, "<", "ponto.txt")){
while(<MOVEMENT>){
chomp;
if(
($mvt_code, $reg, $year, $month, $day, $hour, $minute, $second)=
(/^(\d{12})(\d{7})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/)
){
if($mvt_code=~/^01/){
$year+=2000;
# Entrada do funcionário
$mvt_by_date{"$year$month$day"}{$reg}=3600*$hour+60*$minute+$second;
}
}
}
close(MOVEMENT);
}

# Imprime resultado, devidamente separado por data.
foreach $date (sort(keys(%mvt_by_date))) {
($year, $month, $day)=($date=~/(\d\d\d\d)(\d\d)(\d\d)/);
print "Relatório do dia $day/$month/$year:\n";
foreach $reg (sort(keys(%reg_name))){
printf("\t%7.7s - %-30.30s - ", $reg, $reg_name{$reg});
if(exists($mvt_by_date{$date}{$reg})){
$time=$mvt_by_date{$date}{$reg};
$second=$time%60;
$minute=(($time-$second)/60)%60;
$hour=($time-60*$minute-$second)/3600;
printf(
"%02d:%02d:%02d - %s\n",
$hour, $minute, $second,
$time<=$REFERENCE_TIME? "Presente": "ATRASADO"
);
}
else{
print "--:--:-- - AUSENTE\n";
}
}
print "\f";
}


Acho que, mesmo para quem não sabe Perl, não é difícil de entendê-lo. Note que ele passa somente uma vez por cada arquivo, e imprime resultados no final, classificando por data (poderia ser por usuário, produzindo uma folha de ponto para cada um, com alterações muito simples).

Executando sobre os mesmos dados que o seu (após corrigir a omissão de um dígito no arquivo com o registro do relógio de ponto, em relação ao formato descrito pelo nosso colega lá no início, e alterando algumas linhas, para simular atraso e ausência e, assim, testar todo o programa, em vez de apenas partes), veja a saída.

$ time perl localiza.pl > /tmp/output2

real 0m0.054s
user 0m0.044s
sys 0m0.008s


54 milésimos de segundo, ou mais de 1500 vezes mais rápido, mesmo possuindo mais funcionalidades. E -- o que é mais importante --, escrito em poucos minutos, provavelmente um tempo equivalente ao que você gastou escrevendo seu programa em shell script.


8. Re: Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Pedro Henrique Rissato
pedrorissato

(usa Fedora)

Enviado em 05/11/2014 - 12:48h

Paulo achei sensacional o código e muito legal da sua parte em postá-lo, creio que isso enriquece a discussão sobre o assunto.

Não conheço de Perl, nem Python, por isso não comentei sobre. A princípio, para mim algumas sintaxes ali vistas são "diferentes", mas olhando devagar, é possível entender as passagens feitas, logicamente, produzir um do zero, é outra história.

Achei legal você ter postado o script, pois infelizmente aqui no VOL muitos se prestam a comentar as perguntas sem apresentar efetivas soluções, o que me incomoda de certa forma. Já vi posicionamentos em outros tópicos sobre o porque disto, mas enfim...

Muito bom, pois tanto o autor quanto eu tivemos a chance de aprender algo! xD

Abraços.



9. Re: Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 05/11/2014 - 19:18h

A título de curiosidade, reescrevi em Bash o programa que tinha escrito em Perl (aliás, eu editei o post anterior e modifiquei um pouquinho a versão em Perl, trocando o ponto em que somava 2000 ao ano com dois dígitos, para ficar equivalente à versão em Bash, e isso por causa de uma fraqueza com a aritmética interna do Bash).

Procurei ao máximo evitar comandos externos. Para minha surpresa, tive de usá-los onde menos esperava: embora o Bash possua arrays associativos, ele não possui uma forma de listar as chaves de consulta de modo ordenado. Tive, portanto, de chamar um pipeline com tr e sort, para transpor uma linha com múltiplas colunas em múltiplas linhas e ordená-las.

Tanto o Perl como o Bash possuem arrays simples (indexados com números) e arrays associativos (indexados por uma string). Mas nenhum dos dois possui arrays multidimensionais diretamente. O Perl permite simulá-los facilmente, pois possui o conceito de referência a objeto e permite colocar uma referência a array como elemento de outro array, o que acaba abrindo espaço para uma sintaxe semelhante a de arrays multidimensionais do C. O Bash, no entanto, não tem nada parecido, e seus arrays são estritamente unidimensionais.

A forma de contornar tal carência, possível no programa em questão, foi criar um terceiro array, mvt_dates, indexado somente com as datas que seriam valores de uma das dimensões do array associativo bidimensional. Além isso, pôde-se usar strings compostas, com a forma “data,matrícula”, como chave do array mvt_by_date, simulando a segunda dimensão por meio de chaves de nomes compostos por duas partes. Neste programa, isto não é um problema. No entanto, algumas aplicações que possam trabalhar com strings com qualquer tamanho o conteúdo (inclusive vírgulas ou qualquer outra coisa que pudesse ser convencionalmente usada como separador de dimensões) talvez se tornassem inviáveis.

#!/bin/bash

(( REFERENCE_TIME=8*3600 ))

# Declara arrays associativos
declare -A reg_name mvt_dates mvt_by_date

exec 3< matricula.txt
while read reg name <&3; do
reg_name[$reg]="$name";
done
exec 3<&-

exec 3< ponto.txt
while read line <&3; do
if [[ ${#line} = 31 ]] && [[ "${line/*[^0-9]*/}" = "$line" ]]; then
mvt_code=${line:0:12}
reg=${line:12:7}
year=$((2000+${line:19:2}))
month=${line:21:2}
day=${line:23:2}

# Abaixo eu separo partes da hora, de modo inicialmente
# parecido com as separações acima, mas note que eu fui
# obrigado a acrescentar código para remover o algarismo
# zero antes de valores como "08" e "09". Sem isso, ao
# encontrar o de um número, o Bash entende que o restante
# do número está em base octal, e dá erro ao encontrar um
# algarismo 8 ou 9, que não são válidos nessa base.
hour=${line:25:2}
hour=${hour#0}
minute=${line:27:2}
minute=${minute#0}
second=${line:29:2}
second=${second#0}

if [[ ${mvt_code:0:2} = "01" ]]; then
if [[ ${mvt_dates[$year$month$day]-UNSET} = UNSET ]]; then
mvt_dates[$year$month$day]=""
fi
mvt_by_date[$year$month$day,$reg]=$((3600*hour+60*minute+second))
fi
fi
done
exec 3<&-


#### Imprime resultado, devidamente separado por data.

# Note que tem de chamar comandos externos só para ordenar
# as chaves de pesquisa, pois o shell não tem como fazer
# por conta própria.
exec 3< <( echo "${!mvt_dates[@]}" | tr " " \\n | sort -u )
while read date <&3; do
year=${date:0:4}
month=${date:4:2}
day=${date:6:2}
echo "Relatório do dia $day/$month/$year:"
exec 4< <( echo "${!reg_name[@]}" | tr " " \\n | sort -u )
while read reg <&4; do
printf "\t%7.7s - %-30.30s - " "$reg" "${reg_name[$reg]}"
if [[ ${mvt_by_date[$date,$reg]+SET} = SET ]]; then
time=${mvt_by_date[$date,$reg]}
((second=time%60))
((minute=((time-second)/60)%60))
((hour=(time-60*minute-second)/3600))
printf "%02d:%02d:%02d - " "$hour" "$minute" "$second"
if (( time<=REFERENCE_TIME )); then
echo "Presente"
else
echo "ATRASADO"
fi
else
echo "--:--:-- - AUSENTE"
fi
done
exec 4<&-
printf "\\f"
done
exec 2<&-


O resultado de execução me surpreendeu positivamente -- eu realmente esperava que seria pior -- mas ainda é cerca de 30 vezes mais lento do que a versão em Perl.

$ time ./localiza2.bash > output3 

real 0m1.566s
user 0m1.276s
sys 0m0.228s


O pior, no entanto, é que o programa em shell me parece menos legível do que seu correspondente em Perl, requer os subterfúgios mencionados acima para contornar a não existência de arrays multidimensionais, a falta ordenação de valores, e o parsing “inteligente” de operandos em operações aritméticas. Foi também muito mais demorado de fazer, mesmo sendo uma simples tradução. (Admito que isso foi, em parte, devido a minha falta de familiaridade com arrays associativos no Bash, que me obrigou a ler um bocado a documentação e sites na Internet.)

(Na verdade, há mais um problema latente, que eu não tratei e não sei se teria como tratar facilmente. Se a quantidade de chaves em mvt_dates ou reg_name for absurdamente grande, o echo das pipelines pode falhar ao tentar expandir uma linha de comandos também absurdamente grande ou com excesso de argumentos.)


10. Meu script

Luiz Carlos
luizcarlos18rj

(usa Suse)

Enviado em 17/11/2014 - 15:09h

Agradeço imensamente a ajuda de vcs todos...obrigado pelo tempo despendido e pela solidariedade em ajudar.

Demorei a responder pq gastei uma bom tempo tentando entender as linhas, pois sou iniciante tem comando que nunca vi ainda.

De modo q ainda to elaborando um código meu próprio ainda imperfeito, mas de modo que eu compreenda baseado nos de vcs.

Uma informação é que o arquivo é único, com datas de entrada saída todos os dias, mas eu só executaria o script pela manhã, pelo menos 2 horas depois do início do expediente.

Vou mostrar o código que fiz até agora ( por favor não julguem, to aprendendo ):
----------------------------------------------------------------------------------

#! /bin/bash
#
########## DECLARAÇÃO DE VARIÁVEIS #############
#
data=$(date +%y%m%d)
hoje=$(date +%d%m%y)
ponto_excluir=`ls -1ltr | grep -m 1 ponto_ | awk '{ print $NF}'`
#
########## DECLARAÇÃO DE FUNÇÕES #############
#
ponto_do_dia(){
#Verifica se o arquivo já existe [ -e]
#Se existir, o sobrescreve
#Se não existir, cria-o
#Exclui o arquivo mais antigo
#
if [ -e ponto_$hoje.txt ]; then
#
rm -f ponto_$hoje.txt
grep $data Mvto.TXT >> ponto_$hoje.txt
else
#
grep $data Mvto.TXT >> ponto_$hoje.txt
#
fi
#
}
#
verifica(){
#
#Lê o arquivo linha a linha
#Separa o campo matricula
#pesquisa cada matricula no arquivo ponto do dia
#
#
cat matricula.txt | while read Linha; do
matric=`echo $Linha |awk '{ print $2}'`
grep $matric ponto_$hoje.txt > /tmp/resultado.txt
cat /tmp/resultado.txt
#
cat /tmp/resultado.txt|while read Linha; do
identidade=`echo $Linha|cut -c11-18`
entrada=`echo $Linha|cut -c25-30`
#
#Por questão de organização e estética eu ia declarar essas variáveis lá em cima
#Mas por algum motivo que desconheço deu erro e o script só roda com elas aqui.
#
horav=08
minv=05
segv=00
hora=`echo $entrada | cut -c1-2`
min=`echo $entrada | cut -c3-4`
seg=`echo $entrada | cut -c5-6`
#
grep $identidade matricula.txt |tee -a /tmp/atraso.txt
echo "Horario regresso: $hora:$min:$seg"
#
if [ $hora -gt $horav -o \
$hora -eq $horav -a $min -ge $minv -o \
$hora -eq $hora -a $min -eq $minv -a $seg -ne $seg ]
then
echo "Situacao: Atrasado(a)" |tee -a /tmp/atraso.txt
echo "-------------------------------------------"
echo
else
echo "Situacao: Regressou no horario"
echo "-------------------------------------------"
echo
fi
done
done
}
#
relatorio(){
#
echo "PRESENTES"
echo
cat ponto_$hoje.txt | while read Linha; do
identidade=`echo $Linha|cut -c13-17`
grep $identidade matricula.txt >> /tmp/presentes.txt
done
sort -u /tmp/presentes.txt > /tmp/presentes_org.txt
cat /tmp/presentes_org.txt
echo
echo "FALTAS"
echo
diff -u matricula.txt /tmp/presentes_org.txt | grep '^-[0-9][^+]'
echo
echo "ATRASOS"
echo
grep -B1 "Atrasado(a)" /tmp/atraso.txt | head -1
}
########## INÍCIO #############
#
echo
> /tmp/resultado.txt
> /tmp/presentes.txt
> /tmp/presentes_org.txt
> /tmp/atraso.txt
clear
cd /home/VOL01/S/PONTO/RBCAD/
#Chama as funções
ponto_do_dia
verifica
relatorio
rm -f $ponto_excluir
#FIM
----------------------------------------------------------------------------------
To vendo os códigos de vcs, sei que to usando comandos externos, mas ainda naum to nesse nível é só um script para controle de presença diário.

continuo aguardando sugestões.











11. preciso algumas dicas sobre programação

jose
jonereu

(usa Outra)

Enviado em 23/01/2015 - 23:43h




caros amigos, preciso algumas dicas sobre
programação,

estou com um problema repetitivo e infindável , se por gentileza os amigos

se dispor a ajudar, ficarei muito grato,

é o seguinte.

para realizar meu trabalho, sem erros, tenho que encontrar três
letras repetidas na tela ex. ase , ast , ash, rdt etc.

dentro de um infindável texto .. poderia fazer isto simples usando a
busca do editor. procurando sequencia por sequencia

só que acaba demorando demais , eu preciso que o editor selecione de
forma automática todos os pontos coincidentes com 3 letras dentro de
todo o arquivo de texto

mesmo se as três letras estando junto com outras ex. asr junto com qasr

ou seja encontrar um valor repetido em um texto de forma automática

o texto esta em formato simples .txt

apenas tenho os programas simples na maquina .. word , exccel

att. jose



12. Re: Como criar um script para localizar várias "palavras" no mesmo arquivo de texto. [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 24/01/2015 - 09:58h

Jose, não seria melhor criar um novo tópico específico para suas dúvidas? Este já foi fechado e o assunto principal não ter relação com sua dúvida (bem, tinha pouco haver com o problema solucionado também :P).

Abrindo outro tópico você terá mais chances de ser respondido, e maiores chances de obter respostas de um número maior de pessoas.

jonereu escreveu:

caros amigos, preciso algumas dicas sobre
programação,

estou com um problema repetitivo e infindável , se por gentileza os amigos

se dispor a ajudar, ficarei muito grato,

é o seguinte.

para realizar meu trabalho, sem erros, tenho que encontrar três
letras repetidas na tela ex. ase , ast , ash, rdt etc.

dentro de um infindável texto .. poderia fazer isto simples usando a
busca do editor. procurando sequencia por sequencia

só que acaba demorando demais , eu preciso que o editor selecione de
forma automática todos os pontos coincidentes com 3 letras dentro de
todo o arquivo de texto

mesmo se as três letras estando junto com outras ex. asr junto com qasr

ou seja encontrar um valor repetido em um texto de forma automática

o texto esta em formato simples .txt

apenas tenho os programas simples na maquina .. word , exccel

att. jose





01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts