行値を列値に変換するのに役立ちます。私の入力は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
)。次のスクリプトをコピーしてください。.awk
myScript.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のフィールドがあります。