条件に応じてCSVファイルをマージ

条件に応じてCSVファイルをマージ

私は2つを持っていますCSV日付別ファイル(csv_2014_4_15そしてcsv_2014_4_16)には、基本的な構造といくつかのユニークな列があります。

id,name,created_at,updated_at,other columns

12, joe, 2013-1-1 18:30, 2014-2-1 12:00
56, bob, datetime, datetime

この条件に従って2つのcsvファイルをマージしたいと思います。これまで私のコードは次のようになります。

if (csv_date_x.id == csv_date_x+1.id)
{
   if(csv_date_x.updated_at < csv_date_x.updated_at)
         add csv_date_x+1 row into out.csv
}
else {
   if(csv_date_x+1.created_at == TODAY (yyyy-mm-dd)
         add csv_date_x+1 row into out.csv
}

答え1

この試み:

$ awk -F',' -v t="$(date +"%Y-%-m-%-d")" '
    FNR == NR {
        u[$1] = $4;
        next;
    }
    $4 > u[$1] {
        print;
        next;
    }
    t ~ $3
' file_1 file_2

説明する

  • 今日の日付を取得して変数に保存します。t
  • file_1を読み取るとき、FNR == NR各IDの各更新時間を連想配列に保存しますu。ここで、キーはID、値は更新時間です。
  • file_2を読むとき:

    • idの更新日が配列$4u$4 > u[$1]に格納されているそのidの更新時間よりも大きい場合は、その行を印刷して次の行にジャンプします。
    • 上記の条件が偽の場合は、現在の行の作成日が今日であることを確認します。t ~ $3つまり"2014-7-11" ~ "2014-7-11 12:00"、真であれば行を印刷します。

答え2

csv_date_x は csv_2014_4_15 を意味し、csv_date_x+1 は csv_2014_4_16 を意味すると仮定します。しかし、擬似コードによると、csv_date_xの行は使用しないため、これはマージではなくフィルタに近く、最終的にcsv_2014_4_16のサブセットになります。

これは決して些細なプログラミングではありませんが、収益性の高い方向を知ることができます。

最初の2つのフィールドでエスケープされたコンマを処理する必要がある場合、この種の操作は難しいかもしれません。私はあなたがしないと仮定します。

私はまた、指定しなかったので、2つのファイルを1行ずつ比較できると仮定します。

月と日が常に2桁(先行ゼロ)になるように、まずcsvファイルを正規化する必要があります。その後、次のようにテキストで比較できますawk

sed 's/-\([1-9]\)/-0\1/'

(これは名前、ID、または「その他の列」にハイフンがないと仮定します。そうであれば、日付パターンをより慎重に一致させ、3番目と4番目のフィールドに制限する別のアプローチが必要です。)

このdateプログラムを使用して、フィールドに一致する出力形式で今日の日付を生成し、それを使用する変数として渡しますawk

awk -v Today=$(date +"%Y-%m-%d %H:%M") -v File1=csv_2014_4_15 -v File2=csv_2014_4_16 '
{ getline line1 < File1;
  getline line2 < File2;
  split(line1, f1, ",");
  split(line2, f2, ",");
}
f1[1] == f2[1] { ...; next } # compare IDs this is your first 'if' clause
{ ... } # this is your else clause since the previous ended with "next"

それからあなたは本当に健康でした。 f1 にはファイル 1 の行のフィールドが含まれ、f2 にはファイル 2 の行のフィールドが含まれます。 ID(例:f1 [1]とf2 [1])と日付(例:作成の場合はf1 [2]、更新の場合はf1 [3])を比較できます。希望の行を印刷します。Today今日の日付と比較できます。

awk3番目と4番目のフィールドを分割して日付形式を正規化すると、よりきれいになりますが、最初に見てみる-のはsed簡単です。

また、今日は日付と時刻が含まれています。日付のみを比較したい場合は、dateコマンド仕様からそれを削除できますが、比較する前にcsvフィールドを分割して時間を削除する必要があります。

関連情報