
私は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の更新日が配列
$4
(u
)$4 > u[$1]
に格納されているそのidの更新時間よりも大きい場合は、その行を印刷して次の行にジャンプします。 - 上記の条件が偽の場合は、現在の行の作成日が今日であることを確認します。
t ~ $3
つまり"2014-7-11" ~ "2014-7-11 12:00"
、真であれば行を印刷します。
- idの更新日が配列
答え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
今日の日付と比較できます。
awk
3番目と4番目のフィールドを分割して日付形式を正規化すると、よりきれいになりますが、最初に見てみる-
のはsed
簡単です。
また、今日は日付と時刻が含まれています。日付のみを比較したい場合は、date
コマンド仕様からそれを削除できますが、比較する前にcsvフィールドを分割して時間を削除する必要があります。