|
各行には、可変数の列/フィールドがあるパイプで区切られたファイルがあります。最初の 2 つのフィールドと最後の 2 つのフィールドのみが常に存在し、間には最大 10 個までの多様な (偶数) フィールド数があるため、行には合計最大 14 個のフィールドがあります (2 + 0 .. .10 + 2)。
目的は、「不足している」フィールドを置き換え、ファイルを行ごとに固定数の列を持つファイルに変換することです。
C_A
「変数」フィールドの特徴は、常に...形式の「インデックスキー」C_E
と値で構成されることです。
入力例:
10|100|C_A|val_18|C_D|val_20|50|60
40|200|C_A|val_5|C_B|val_10|C_C|val_30|C_D|val_90|C_E|val_83|40|45
80|100|C_E|val_90|50|60
予想される結果は次のとおりです。
10|100|C_A|val_18|||||C_D|val_20|||50|60
40|200|C_A|val_5|C_B|val_10|C_C|val_30|C_D|val_90|C_E|val_83|40|45
80|100|||||||||C_E|val_90|50|60
ベストアンサー1
GNU awk
名前をフィールドインデックスにマッピングすることでこの問題を解決できます。
- C_A => $3
- C_B => $5 ...など。
$ awk '
BEGIN {
OFS = FS = "|"
n = split("A-B-C-D-E", x, "-")
for (i=1; i<=n; ++i) h["C_" x[i]] = 2*(i-1) + 3
}
{
# record which out of
# ca/cb/.../ce present
for (i=3; i<NF-2; i+=2) seen[$i] = $(i+1)
# store fields in preparation
# for re-filling them based on seen
nf = split($0, f, FS); $0=""
# fill up the first two..easy does it
$(1) = f[1]
$(2) = f[2]
# recall which fields c_?
# were seen then fill up
# corresponding field and field value
for (var in h) {
i = h[var]
if (var in seen) {
$(i) = var
$(i+1) = seen[var]
} else { $(i) = $(i+1) = ""}
}
# append the last two fields
$(NF+1) = f[nf-1]
$(NF+1) = f[nf]
# above line **NOT** a typo
# clear out the array seen
# for the next iteration
split("", seen, ".")
}1
' file
結果:
10|100|C_A|val_18|||||C_D|val_20|||50|60
40|200|C_A|val_5|C_B|val_10|C_C|val_30|C_D|val_90|C_E|val_83|40|45
80|100|||||||||C_E|val_90|50|60