一致する行を1行にマージ

一致する行を1行にマージ

awk重複した行を見つけて1つにマージするコマンドが停止しました。

私のファイルは次のとおりです(ヘッダーなし)。すでに2列に並んでいます。

1, abc, 123, , , , , , , , , ,
2, xyz, 123, , , , , , , , , ,
3, pqr, 123, , , , , , , , , ,
4, pqr, 123, , ,10, ,12, , , , ,
5, pqr, 123, , , , , , , ,1,2,
6, def, 123, , , , , , , , , ,
7, lmn, 123, , , , , , , , , ,
8, lmn, 123, , ,22, ,11, , , , ,
9, tuv, 123, , , , , , , , , ,
10, qrs, 123, , , , , , , , , ,

出力は次のとおりです。

1, abc, 123, , , , , , , , , ,
2, xyz, 123, , , , , , , , , ,
3, pqr, 123, , ,10, ,12, , ,1,2,
6, def, 123, , , , , , , , , ,
7, lmn, 123, , , 22, 11, , , , , ,
9, tuv, 123, , , , , , , , , ,
10, qrs, 123, , , , , , , , , ,

助けてくれてありがとう。事前にありがとう

ベストアンサー1

これは1行のコードで行うことができますが、スクリプト全体を書くのは難しいです。

#!/usr/bin/awk -f
# This shebang works on Mac; Linux boxes should use:
#!/bin/awk -f

BEGIN {
  FS = ", *";
  OFS = ", "
}

function printhold() {
  for (i=1; i<size; i++) {
    printf "%s", hold[i] OFS
  }
  print hold[size]
}

NR == 1 {
  size = split ($0, hold, ", *")
  next
}

hold[2] == $2 {
  for (i=4; i<=size; i++) {
    if (hold[i] == "") {
      hold[i] = $i
    }
  }
  next
}

{
  printhold()
  size = split ($0, hold, ", *")
} 

END {
  printhold()
}

高レベルで行われる作業は次のとおりです。

  1. 一行ずつ覚えておいてください。 (印刷しないでください。)
  2. 次の行を見てください。フィールド2が予約された行のフィールド2と一致する場合:
  3. 行を保持する各フィールドに対してフィールドが空の場合、現在表示されている行の対応するフィールド値に設定されます。
  4. 2に進みます。
  5. 現在行のフィールド2いいえスケジュールされたフィールド2と一致します(つまり、ステップ2のテストが失敗します)。
  6. 予約済みライン印刷
  7. メモリ内の行を次の行(上記の5で見つかった一致しない行)に置き換えます。
  8. 2に進みます。
  9. ファイルの終わりに達すると、残りの行を印刷します。

上記のコードロジックの重要な部分(実際に行をマージする部分)は次のとおりです。

hold[2] == $2 {
  for (i=4; i<=size; i++) {
    if (hold[i] == "") {
      hold[i] = $i
    }
  }
  next
}

これは概略説明のステップ2〜4と一致します。

おすすめ記事