最初の列に.csv
日付と時刻のフォーマットを含むファイルがあります。列はセミコロンで区切られています。01/20/2016 23:53:01
01/21/2016 03:03:01;18616;0;1
01/21/2016 03:13:01;29040;36553;2
…
の上それでbashコマンドを見つけました
date -d '06/12/2012 07:21:22' +"%s"
これは私が望んでいることのようです。私は今、awk
最初の列を置き換えるために統合しようとしています。私は同様の問題に対する答え:
awk -F'"' -v OFS='"' '$8 {cmd="date -d \""$8"\" +%FT%T%z"; cmd | getline $8; close(cmd)} 1' input.json
これを自分の入力に適応させようとしましたが、空の出力しか得られませんでした。
答え1
質問を書きながら、ついに私はラバーダックに成功しました。これが私の解決策です:
awk -F';' -v OFS=';' '$1 {cmd="date -d \""$1"\" +%s"; cmd | getline $1; close(cmd)} 1' datetime.csv > unix.csv
それは 2 つの要因の組み合わせでした。オンを忘れていたこと"
と+%s"
、入力した行が壊れていたことです。
答え2
GNU dateには、-f
ファイルから読み込んだ日付を行ごとに変換するオプションがあります。ファイルが長い場合は、date
行ごとに呼び出すよりも高速です。日付は行に単独で存在する必要があります。したがって、最初の列(cut -d \; -f 1
)を分離し、それを実行してdate -f -
変換を実行し、ペースト残りの列の結果。
paste -d \; <(<input cut -d \; -f 1 | date -f - +%s) <(<input cut -d \; -f 2-)
これは、シェルがサポートしていることを前提としていますプロセス置換(ksh93、bash、zsh)。プレーンsh
では、サポートしている Unix バリアント/dev/fd
(ほとんどがサポートしています) で、ファイル記述子のシャッフルを使用できます。
<input cut -d \; -f 2- | {
exec 3<&0
<input cut -d \; -f 1 | date -f - +%s | paste -d \; - /dev/fd/3
}
答え3
うーん。これは少し前の話ですが、提案してもいいかなと思います。
ファイルの行数が多い場合は、シェルに入って各行に対して「date」を呼び出すと少し遅くなることは間違いありません。
Google カレンダーから抽出したタイムシートのエントリを処理し、HTML を出力して PDF 請求書に変換するスクリプトを記述するつもりでした。しかし、それについて話しているうちに長くなりすぎてしまいました。そのため、読みにくくなるようにコードだけを紹介します。
私は AWK 関数の gensub と mktime [https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html] を使用しています。mktime 関数は、datespec 形式「YYYY MM DD HH MM SS [DST]」での入力を期待しているため、入力をシフトする必要があり、そこで gensub 関数が役立ちます。私が用意したものは次のとおりです...
awk -F';' -v OFS=';' '{ $1=mktime(gensub(/(..)\/(..)\/(....) (..):(..):(..)/, "\\3 \\1 \\2 \\4 \\5 \\6", 1, $1)); } 1' datetime.csv > unix.csv
私はこれを少し違ったやり方で行い、最初の引数に書き戻すのではなく、個々の引数を print で出力します。少しだけ自己文書化が進みます ;) ティムトウトディ
awk -F';' -v OFS=';' '{ print mktime(gensub(/(..)\/(..)\/(....) (..):(..):(..)/, "\\3 \\1 \\2 \\4 \\5 \\6", 1, $1)), $2, $3, $4; }' datetime.csv > unix.csv
スクリプトは少し冗長ですが、パフォーマンスが向上することを期待しています。
これがあなたや同じことを見ている他の人の役に立つことを願っています。