extração de números específicos do arquivo de texto e conversão para ano mês e dia

0

Por exemplo, eu tenho um arquivo de dados como

joze0670.14o
joze0680.14o
joze0690.14o

Eu preciso extrair 3 dígitos (dia do ano) após os primeiros 4 caracteres e 2 dígitos (ano começa com 2000) antes de "o". Então eu quero encontrar ano-mês-dia para cada dado e atribuí-los à variável.

Digamos que doy_1=067;year_1=2014 para os primeiros dados. Então as variáveis são atribuídas; year=2014;month=03;day=08

Vou usar essas variáveis dentro do loop mais tarde (como $ year, $ month, $ day).

Qual é o caminho adequado para esse processo?

    
por deepblue_86 20.10.2015 / 15:42

3 respostas

3

Você pode usar uma combinação de sed , xargs e date :

$ sed -r 's/.{4}([0-9]{3}).*//' input | xargs -i date -d '2014-01-01 + {} days - 1 day' '+%Y %m %d'
2014 03 08
2014 03 09
2014 03 10

Então você pode read os valores em variáveis:

sed -r 's/.{4}([0-9]{3}).*//' input | xargs -i date -d '2014-01-01 + {} days - 1 day' '+%Y %m %d' | 
  while read year month day
  do
     echo "Year: $year"
     echo "Month: $month"
     echo "Day: $day"
  done 

Referências:

O código anterior usava um ano fixo. Para usar o ano dado pela extensão, podemos dizer a sed para criar uma string de data completa para date :

sed -r 's/.{4}([0-9]{3}).\.([0-9]{2}).*/20-01-01 +  days - 1 day/' input | xargs -i date -d {} '+%Y %m %d'
    
por muru 20.10.2015 / 16:42
1

Por esse script

#!/usr/bin/env bash
while read -r line; do 
    year=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/ /' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%Y\"")}')
    month=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/ /' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%m\"")}')
    day=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/ /' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%d\"")}')
done <foo

Exemplo

#!/usr/bin/env bash
while read -r line; do 
    year=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/ /' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%Y\"")}')
    month=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/ /' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%m\"")}')
    day=$(sed 's/^.\{4,4\}\([0-9]\{3,3\}\)0\.\(.*\)o/ /' <(echo "$line") | awk '{system("date -d \"01/01/"$2" +"$1" days -1 days\" +\"%d\"")}')

    echo "$year"
    echo "$month"
    echo "$day"
done <foo

fornece a saída

2014
03
08
2014
03
09
2014
03
10
    
por A.B. 20.10.2015 / 16:27
1

Ideia Básica

O horário Unix epoch opera em segundos. O script abaixo extrai um ano, converte o primeiro dia do ano em unix epoch time, compensa-o por (86400 segundos por dia) * (dias extraídos - 1) e converte de volta para o formato legível por humanos

Script

#!/bin/bash
#set -x
SECONDSINYEAR=86400

while  read line && [[ -n $line ]];do
   ARRAY=( $( awk -F '.' '!/^$/{gsub(/[a-z,A-Z]/,""); print substr($1,1,3),$2 }' <<< "$line") )
   ARRAY[0]=$( expr ${ARRAY[0]} - 1  )
   DAYOFFSET=$( expr ${ARRAY[0]} \* 86400 )
   BASEDATE=$(date -d ${ARRAY[1]}0101 +%s)
   ACTUALDATE=$( expr $BASEDATE + $DAYOFFSET )

   date -d "@$ACTUALDATE" +%d" "%m" "%Y

done  < $1

Resultado

xieerqi:$ cat testFile.txt                                                
joze0670.14o
joze0680.14o
joze0690.14o


xieerqi:$ ./extractDate.sh testFile.txt                                   
08 03 2014
09 03 2014
10 03 2014
    
por Sergiy Kolodyazhnyy 20.10.2015 / 17:38