行を列に変換する方法

行を列に変換する方法

行値を列値に変換するのに役立ちます。私の入力はfile.dat次のとおりです

最初の2つのフィールドはそれぞれアルファベット文字列と数字です。入力には常に同じ数のフィールドがあります。6

入力する

A|1|DLT|07:30|10:30|34
A|1|STG|07:30|10:30|NA
A|1|MAIN|06:30|10:30|NA
A|2|STG|07:30|10:30|NA
A|2|UNLD|04:30|10:30|90
B|1|DLT|03:30|10:30|34
B|1|STG|07:30|09:30|NA
B|1|MAIN|07:25|10:30|NA
B|1|UNLD|05:30|12:30|8

出力に変化があります。出力フィールドすべての行には18個のフィールドがあり、各行には入力ファイルの最初の2つのフィールドがあり、その後には次の順序で3番目、...、18番目のフィールドがあります。ここで、空のフィールドは入力ファイルから欠落している行です。レコードの順序はDLTで、STG、MAIN、およびUNLDの後に対応するレコードが続きます。

出力

A|1|DLT|07:30|10:30|34|STG|07:30|10:30|NA|MAIN|06:30|10:30|NA|||| 
A|2|||||STG|07:30|10:30|NA|||||UNLD|04:30|10:30|90
B|1|DLT|03:30|10:30|34|STG|07:30|09:30|NA|MAIN|07:25|10:30|NA|UNLD|05:30|12:30|8
  • A | 1 UNLDがありません
  • A | 2にはDLTとMAINはありません。
  • 記録は失われません。

同様に、入力ファイルの3番目のフィールドに対応するレコードが見つからない場合は、出力フィールドが次のようになるように空の値に置き換える必要があります。18地域

ベストアンサー1

私のawkアドバイス:

awk -F'|' '{ if (a[$1$2] == "") {
               a[$1$2] = $0
             } 
             else {
               a[$1$2] = a[$1$2]","$3"|"$4"|"$5"|"$6
             }
           }
           END {
             for (key in a) {
               print a[key]
             }
           }' <input.txt | sort

説明する

この-F'|'オプションは定義しますフィールド区切り記号awk行のフィールドを解析するために使用されます)はファイル形式なので、文字「|」として使用されます。

a[...]配列です。配列はawkインデックスではなく、Python辞書に多少似ています。これは実際に文字列です。入力ファイルの各行のテストでは、エントリが存在する場合は最初の2つのフィールド(最初の行など)if (a[$1$2] == "")に対応するキーを確認します。$1$2 = A1そうでない場合(A|1|...最初の行を読み取る)、行全体がこのキー(a[$1$2] = $0)に保存されます。すでにコンテンツがある場合(A|1|...別の行が保存されている場合)、エントリをコンマで連結し、「|」を使用してフィールドを3から6まで区切ります。 (a[$1$2] = a[$1$2]","$3"|"$4"|"$5"|"$6)。

最後に、ファイルの検索が完了したら、各キーのエントリを出力する必要があります。私たちはENDこれをブロックで行います(このコマンドはすべてのファイルを読み取った後に実行されます)。これを行うには、for (key in a)配列()のすべてのキーを繰り返し、各キーの項目を印刷します。

その後、最終出力はにパイプされますsort。配列キーは英数字で巡回されないため、後で行などをawk取得できるように出力をソートする方がきれいになります。A|1|...A|2|...


最後の編集により、すべてが少しトリッキーになりました。必要な指示がawk多少複雑になる可能性があるため、スクリプトファイルを生成することをお勧めします(例:拡張子付きのテキストファイルの生成awk)。次のスクリプトをコピーしてください。.awkmyScript.awk

BEGIN { FS="|" }

$3 == "DLT" {
  dlt[$1"|"$2]=$3"|"$4"|"$5"|"$6
  a[$1"|"$2]++
}

$3 == "STG" {
  stg[$1"|"$2]=$3"|"$4"|"$5"|"$6
  a[$1"|"$2]++
}

$3 == "MAIN" {
  main[$1"|"$2]=$3"|"$4"|"$5"|"$6
  a[$1"|"$2]++
}

$3 == "UNLD" {
  unld[$1"|"$2]=$3"|"$4"|"$5"|"$6
  a[$1"|"$2]++
}

END {
  for (key in a) {
    if (dlt[key] == "") dlt[key]="|||"
    if (stg[key] == "") stg[key]="|||"
    if (main[key] == "") main[key]="|||"
    if (unld[key] == "") unld[key]="|||"
    print key"|"dlt[key]"|"stg[key]"|"main[key]"|"unld[key]          
  }
}

それを書く:

awk -f myScript.awk <input.txt | sort

私の元の答えの説明を理解したら、このアルゴリズムも理解できます。今回は、各データ型(dlt、stg、main、unld)の配列を作成し、その値を最初の2つのフィールドに対応するキーに保存します。配列はaすべての可能なキーを追跡するために使用されます。最後に、配列のキーを繰り返しa、そのキーのデータ配列の1つが空の場合は、必要に応じて "|||"を入力し、各行に18のフィールドがあります。

おすすめ記事