ファイルから複数のデータを抽出してcsvファイルに保存する方法は?

ファイルから複数のデータを抽出してcsvファイルに保存する方法は?

次の形式のファイルがあります。

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

CSV 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
.......

appel00:00:XX を使用しようとするたびに3番目のフィールドの値を抽出する必要がありますが、awk特に5番目のフィールドが2つの単語で構成されているため、スクリプトを正しくインポートすることはできませんでしたRegulated F2。個々の単語で抽出する方法がわかりません。

助けてください!

答え1

パールの使用:

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

拡張スクリプト(実行ファイルを使用してchmod +x script.pl実行を使用./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) 
}

ヘッダーを変更して調整し、print("\t\tT1\tF2\tI1\tF3\tRegulated F2\tFR T1");出力フィールド区切り文字を変更して調整できます$, = "\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
% 

答え2

仕事はとても簡単です。日付で始まるか、月の列を含む行を無視します。最初の行にテスト時間が含まれている場合は、その時間と他のすべての行に対して3番目の列が取得されます。以下のスクリプトがAWKまさにそのことをします。

デモ:

$> ./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

スクリプトソース

#!/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] 

}

関連情報