compara arquivos com base em duas colunas e adiciona campo

2

Eu tenho arquivos com data e hora em coluna no formato "AAAA MM DD HHMM" mais uma variável (temperatura) e quero convertê-los em formato YYYY DDD (e manter hora e temperatura como estão). Eles se parecem com isso, mas a mesma data aparece várias vezes no arquivo:

1980 01 01 0100 3.3
1982 04 11 0400 2.2
1985 12 04 0700 1.7
1995 12 31 1000 2.2

Eu criei um arquivo de índice (1980-2017) com o número de dias a serem adicionados a cada data do primeiro arquivo para obter o dia acumulativo do ano DDD (última coluna). O primeiro ano é assim (1980 foi um ano bissexto):

1980 01 31  000
1980 02 29  031
1980 03 31  060
1980 04 30  090
1980 05 31  121
1980 06 30  152
1980 07 31  182
1980 08 31  213
1980 09 30  244
1980 10 31  274
1980 11 30  305
1980 12 31  335

Estou tentando comparar os dois arquivos com base nas duas primeiras colunas e se eles correspondem para adicionar a quarta coluna do arquivo2 à terceira coluna do arquivo 1 e terminar com algo parecido com isto:

1980 001 0100 3.3 
1982 101 0400 2.2 
1985 346 0700 1.7 
1995 365 1000 2.2

Consegui comparar as duas colunas dos arquivos e adicionar as duas colunas com o awk abaixo:

awk -F' ' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' junktemp matrix_sample | awk '{print $1, $3+$4}' 

mas desta forma eu perco $ 4 e $ 5 (hora e temperatura). Existe uma maneira de combinar as duas funções awk e obter $ 4 e $ 5 de file1 no resultado também? Qualquer ajuda muito apreciada.

    
por sprite 25.05.2017 / 17:39

2 respostas

0

É difícil testar, pois você só forneceu correspondências possíveis para um único ano, mas

awk 'NR==FNR{c[$1$2]=$4; next} ($1$2 in c) {$3 = sprintf("%03d", $3 + c[$1$2])} {print $1, $3, $4, $5}' file2 file1
1980 001 0100 3.3
1982 11 0400 2.2
1985 04 0700 1.7
1995 31 1000 2.2
    
por 25.05.2017 / 18:08
0

Assumindo que o GNU date e bash (ou qualquer shell que processe substituição com <(...) ) e que os dados sejam armazenados no arquivo file , como nos primeiros dados de exemplo na pergunta:

$ paste -d ' ' <( date -f <( cut -d ' ' -f1-3 file | tr ' ' '-' ) +"%Y %j" ) \
               <( cut -d ' ' -f4-5 file )
1980 001 0100 3.3
1982 101 0400 2.2
1985 338 0700 1.7
1995 365 1000 2.2
  • O primeiro cut é usado junto com tr para transformar as datas nas três primeiras colunas dos dados de entrada no formulário YYYY-MM-DD .
  • Isso é passado para o GNU date para processamento em lote por meio de sua opção -f . Como saída, solicitamos datas usando o formato %Y %j . %Y é o ano no formulário YYYY e %j é o dia do ano no formulário DDD .
  • Isso é colado junto com as duas últimas colunas do arquivo original (produzido pelo segundo cut ) usando um único espaço como um delimitador.

Esta é uma transformação direta dos dados originais para o resultado final, evitando a necessidade do arquivo de índice que você criou.

    
por 18.09.2017 / 00:42

Tags