最初の列には、日付/時刻を表す文字列を含むCSVがあります。追加の列を追加し、日付/時刻をエポックに変換したいと思います。
私は以下を試しました:
awk -F "," 'BEGIN{ OFS="," } {$14=$(date -jf "%m/%d/%Y %H:%M:%S %p" $1 "+%s"); print}’ mycsv.csv > test
私は得る:
awk: illegal field $(0%m/%d/%Y %H:%M:%S %p"1/30/2017 11:14:55 AM"+%s), name "(null)"
input record number 1, file mycsv.csv
source line number 1
このフィールドの日付変換が機能することがわかっているため、いくつかの構文エラーが発生します。
私がしたいことはどうすればいいですか?
答え1
私はGNUを持っているdate
ので、コマンドラインオプションは異なります。しかし、問題はawkの構文のようです。$(...)
awkスクリプトではシェルサブプロセス設定を使用できません。system()
文字列を渡す関数が必要です。したがって、有効なシェルコマンドをawk文字列として設定する必要があり、それをawkスクリプト内でシステムに渡すことができます。
このような:
awk -F "," 'BEGIN{ OFS="," } {$14=system("date -jf \"%m/%d/%Y %H:%M:%S %p\" \""$1"\" \"+%s\""); print}' mycsv.csv > test
またはより良い読みやすさのために
awk -F "," '
BEGIN{ OFS="," }
{
$14 = system("date -jf \"%m/%d/%Y %H:%M:%S %p\" \"" $1 "\" \"+%s\"");
print
}' \
mycsv.csv > test
答え2
awk
GNU(私の意見ではOSXで動作する必要があると思う)がある場合は、システムに依存するのではなくbrew
内部GNUを使用できます。mktime
strftime
date
残念ながら、入力形式は次の形式ではありません。日付仕様必要な形式mktime
なので、時間文字列を一部分割して再配置する必要があります。例えば、与えられた
$ cat file.csv
09/23/2016 11:12:19 AM,field2,field3
それから
gawk -F, '
{
split($1,a,/[/: ]/);
ts = sprintf("%4d %02d %02d %2d %2d %2d", a[3], a[2], a[1], a[7] ~ /^[Pp]/ ? a[4]+12 : a[4], a[5], a[6]);
$0 = strftime("%s", mktime(ts)) FS $0
} 1' file.csv
1510243939,09/23/2016 11:12:19 AM,field2,field3
答え3
Miller(mlr
macOSでHomebrewを介してパッケージとして利用可能miller
)を使用し、入力がヘッダーなしのCSVファイルであり、フィールド1のフォーマットされた日付を解析してフィールド14にUnixタイムスタンプを書き込もうとします。
mlr --csv -N put '$14 = strptime($1,"%m/%d/%Y %H:%M:%S %p")' mycsv.csv
ヘッダーがある場合は、その-N
オプションを削除し、数値フィールドの代わりに名前付きフィールドを使用します(例:)$timestamp = strptime($date, ...)
。
このstrptime()
関数は提供されたパターンを使用してフォーマットされた日付を解析し、Unixタイムスタンプを返します。
質問に記載されている日付の場合、UTCタイムゾーンにあると仮定すると、新しいフィールドの値はです1485774895.000000
。ローカルタイムゾーンを考慮するには、strptime_local()
代わりにを使用してくださいstrptime()
。 Unixタイムスタンプの整数部分だけが必要な場合は呼び出しstrptime()
をint(...)
。