Como extrair vários dados de um arquivo e armazená-lo em um arquivo csv?

3

Eu tenho um arquivo no seguinte formato:

19-08-02  Name                         appel    ok    hope    local  merge   (mk)
                                                        juin    nov    sept    oct
00:00:t1  T1                            299       0      24      8      3     64
          F2                            119       0      11      8      3     62
          I1                             25       0       2      9      4     64
          F3                            105       0      10      7      3     61
          Regulated F2                    0       0       0
          FR T1                         104       0      10      7      3     61
00:00:t2  T1                            649       0      24      8      3     64
          F2                            119       0      11      8      3     62
          I1                            225       0       2      9      4     64
          F3                            165       0      10      7      3     61
          Regulated F2                    5       0       0
          FR T1                         102       0      10      7      3     61
20-08-02  Name                          appel    ok    hope    local  merge   (mk)
                                                        juin    nov    sept    oct
00:00:t5  T1                            800       0      24      8      3     64
          F2                            111       0      11      8      3     62
          I1                             250      0       2      9      4     64
          F3                            105       0      10      7      3     61
          Regulated F2                    0       0       0
          FR T1                         100       0      10      7      3     61

e eu quero extrair alguns dados e escrevê-los em outro arquivo CSV file no seguinte formato:

            T1   F2     I1      F3    Regulated F2    FR T1
00:00:t1    299  119    25      105       0           104  
00:00:t2    649  119    225     165       5           102
00:00:t5    800  111    250     105       0           100
.......

Eu só preciso extrair os valores no terceiro campo appel every 00:00:XX Eu tentei usar awk , mas eu não consegui ter o script certo, especialmente o quinto é composto de duas palavras: Regulated F2 . Eu não sei como extraí-lo como uma única palavra.

Qualquer ajuda, por favor!

    
por pietà 26.02.2016 / 15:58

2 respostas

5

Usando o Perl:

perl -lane 'BEGIN{ print("\t\tT1\tF2\tI1\tF3\tRegulated F2\tFR T1"); $, = "\t" } if($F[0] =~ /00:00:t[0-9]+/){ @f[0] = $F[0]; @f[1] = $F[2]; for($i = 2; $i < 7; $i++) { $_ = <>; @F=split(); if($i < 5){ $f[$i] = $F[1] }else{ $f[$i] = $F[2] } } print(@f) }' file

Script expandido (para tornar-se executável com chmod +x script.pl e para ser executado com ./script.pl file ):

#!/usr/bin/perl -lan
BEGIN {
    print("\t\tT1\tF2\tI1\tF3\tRegulated F2\tFR T1");
    $, = "\t"
}
if($F[0] =~ /00:00:t[0-9]+/) {
    $f[0] = $F[0];
    $f[1] = $F[2];
    for($i = 2; $i < 7; $i++) {
        $_ = <>;
        @F=split();
        if($i < 5) {
            $f[$i] = $F[1]
        }
        else {
            $f[$i] = $F[2]
        }
    }
    print(@f) 
}

Você pode ajustar o cabeçalho modificando print("\t\tT1\tF2\tI1\tF3\tRegulated F2\tFR T1"); e o separador do campo de saída modificando $, = "\t" .

% cat file
19-08-02  Name                         appel    ok    hope    local  merge   (mk)
                                                        juin    nov    sept    oct
00:00:t1  T1                            299       0      24      8      3     64
          F2                            119       0      11      8      3     62
          I1                             25       0       2      9      4     64
          F3                            105       0      10      7      3     61
          Regulated F2                    0       0       0
          FR T1                         104       0      10      7      3     61
00:00:t2  T1                            649       0      24      8      3     64
          F2                            119       0      11      8      3     62
          I1                            225       0       2      9      4     64
          F3                            165       0      10      7      3     61
          Regulated F2                    5       0       0
          FR T1                         102       0      10      7      3     61
20-08-02  Name                          appel    ok    hope    local  merge   (mk)
                                                        juin    nov    sept    oct
00:00:t5  T1                            800       0      24      8      3     64
          F2                            111       0      11      8      3     62
          I1                             250      0       2      9      4     64
          F3                            105       0      10      7      3     61
          Regulated F2                    0       0       0
          FR T1                         100       0      10      7      3     61
% perl -lane 'BEGIN{ print("\t\tT1\tF2\tI1\tF3\tRegulated F2\tFR T1"); $, = "\t" } if($F[0] =~ /00:00:t[0-9]+/){ @f[0] = $F[0]; @f[1] = $F[2]; for($i = 2; $i < 7; $i++) { $_ = <>; @F=split(); if($i < 5){ $f[$i] = $F[1] }else{ $f[$i] = $F[2] } } print(@f) }' file
        T1  F2  I1  F3  Regulated F2    FR T1
00:00:t1    299 119 25  105 0   104
00:00:t2    649 119 225 165 5   102
00:00:t5    800 111 250 105 0   100
% 
    
por 26.02.2016 / 18:37
5

A tarefa é bastante simples: ignorar linhas que começam com data ou linhas que contêm colunas de mês; se a primeira linha contiver a hora do teste, pegue o tempo e a terceira coluna; para todas as outras linhas - pegue a segunda coluna. O script AWK abaixo faz exatamente isso.

Demonstração:

$> ./data2cvs.awk  testData.txt                                                  
T1,F2,I1,F3,Regulated F2,FR T1
00:00:t1,299,119,25,105,0,104
00:00:t2,649,119,225,165,5,102
00:00:t5,800,111,250,105,0,100

Origem do script

#!/usr/bin/awk -f 

BEGIN {  
  HEADER="T1,F2,I1,F3,Regulated F2,FR T1"; print HEADER  
} 
# Ignore lines containing date and month
$1~/^[[:digit:]]{2}-.+/ || $0~/juin.*nov.*sept.*oct/ { 
     next ; 
}  
# Grab test time and first data value 
# Essentially doing something like sprintf in C
# to a string of arrays
$1~/^[[:digit:]]{2}:.+/{ 
     count++
     DATA[count]=$1","$3 
  }   
# grab remaining data values
$1 !~ /^[[:digit:]]{2}:.+/{

   if ($1~/Regulated/ || $1~/FR/){ 
      DATA[count]=DATA[count]","$3
   }
   else {
       DATA[count]=DATA[count]","$2 ;
   }
} 
# print gathered data to STDIN
END{ 
   for (i=1;i<=count;i++) print DATA[i] 

}
    
por 26.02.2016 / 19:24