msoliver
(usa Debian)
Enviado em 15/02/2023 - 19:35h
SamL escreveu:
Olá, alguém que possa me ajudar entender como criar um comando básico em shell que leia um padrão como:
Num txt:
dia/mes/ano [ignora o que tem aqui] de hora:min[:segundos] até às hora:min[:segundos]
Eu sei muito bem fazer isso em C ou C++, mas eu quero inovar dessa vez fazer em shell script.
Não quero que façam por mim, quero aprender como fazer em shell.
O que preciso saber é:
1-como ler linha a linha o txt
2-depois de ler a linha, como "separar o joio do trigo?", no caso deixando só a data depois as duas horas? (que as vezes vem com segundos como opcional)
3-depois disso, como que comando eu uso pra parsear pra data e hora? Me dê exemplos que entendo melhor.
4-como com a data e horas, como fazer a diferença em minutos entre as duas horas?
É tudo que pensei no momento.
https://nerdki.blogspot.com/ acessa ai, é grátis
Não gostou? O ícone da casinha é serventia do site!
Boa noite SamL.
Para ler linha a linha, é bem simples:
while read line;do
echo $line
done<arquivo.txt
Poste um exemplo do seu arquivo,
de acordo com o conteúdo das linhas, usa se o comando mais elaborado/apropriado....
Por exemplo:
Se seguem um padrão, mesmo número de campos, uso o awk
Se tem variação, uso regex para "pegar" o que preciso . . . .
----------------------------------------------------------------------------------------------------------------
Exemplo: arq sem padrão
cat arq.txt
01/02/2023 ignora o que tem aqui de 08:10:30 até às 18:00:00
02/02/2023 ignora o que tem aqui tambem de 08:20:30 até às 18:30:00
03/02/2023 ignora o que tem aqui tambem novamente de 08:30:30 até às 18:40:00
sed -r 's/[^0-9 :/]+//g;s/[ ]{2,}/ /g' arq.txt
01/02/2023 08:10:30 18:00:00
02/02/2023 08:20:30 18:30:00
03/02/2023 08:30:30 18:40:00
----------------------------------------------------------------------------------------------------------------
arq com padrão
cat arq.txt
01/02/2023 ignora o que tem aqui de 08:10:30 até às 18:00:00
02/02/2023 ignora o que tem aqui de 08:20:30 até às 18:30:00
03/02/2023 ignora o que tem aqui de 08:30:30 até às 18:40:00
awk '{print $1,$8,$11}' arq.txt
01/02/2023 08:10:30 18:00:00
02/02/2023 08:20:30 18:30:00
03/02/2023 08:30:30 18:40:00
----------------------------------------------------------------------------------------------------------------
Exemplo:
sed -r 's/[^0-9 :/]+//g;s/[ ]{2,}|[/:]/ /g' arq.txt|awk '{data=$3" "$2" "$1;ti=strftime("%s",mktime(data" "$4" "$5" "$6));tf= strftime("%s",mktime(data" "$7" "$8" "$9));printf "Minutos: %s\n",(tf-ti)/60 }'
Minutos: 600
Minutos: 609.5
Minutos: 849.5
-----------------------------------------------------------------------------------------------------------------
Editado
exec 3< <(sed -r 's/[^0-9 :/]+//g;s/[ ]{2,}|[/:]/ /g' arq.txt);
cat calc.awk
BEGIN {h = 3600;}
{
data = $3 " " $2 " " $1
ti = mktime(data " " $4 " " $5 " " $6)
tf = mktime(data " " $7 " " $8 " " $9)
dif = tf - ti
dh = int(dif / h)
dm = int((dif % h) / 60)
ds = int((dif % h) % 60)
mn = dif / 60
gsub(" ", "/", data)
printf "Dt:%s Hor:%02d Min:%02d Seg:%02d Min_total:%.2f uts:%s\n",data, dh, dm, ds, mn, dif
}
awk -f calc.awk "/dev/fd/3";exec 3<&-;
#----------------------------------------------------------------#
Solução em bash
exec 3< <(sed -r 's/[^0-9 :/]+//g;s/[ ]{2,}|[/]/ /g' arq.txt);
while IFS=" " read -a c -u3;do
data=${c[2]}"-"${c[1]}"-"${c[0]};
ent=$(date -d"${data} ${c[3]}" +%s);
sai=$(date -d"${data} ${c[4]}" +%s);
dm=$(((${sai}-${ent})/60));
dh=$((${dm}/60));
printf "Dt:%s Min:%s Hr:%s\n" ${data//-/\/} ${dm} ${dh};
done
exec 3<&-;
#FIM#
______________________________________________________________________
Att.: Marcelo Oliver
______________________________________________________________________