web-dev-qa-db-ja.com

AWKでの日付の変換

Fri Jan 02 18:23の行に沿ったタイムスタンプを含む、テキストの多くの列を含むファイルがあり、その日付をMM/DD/YYYY HH:MM形式に変換する必要があります。

標準の「date」ツールとawkgetlineを使用して変換を実行しようとしていますが、フィールドを「date」コマンドに期待どおりの形式(「または」で引用)で渡す方法がわかりません。 s、)getlineには、引用符で囲まれたコマンド文字列も必要です。

"date -d '$1 $2 $3 $4' +'%D %H:%M'" | getline varのようなもの

考えてみると、私が本当に求めているのは、awk変数を文字列に埋め込む方法だと思います。

17
PStibbons

あなたはこれを試すことができます。指定した日付だけがファイルにあると仮定します

awk '
{
    cmd ="date \"+%m/%d/%Y %H:%M\" -d \""$1" "$2" "$3" "$4"\""
    cmd | getline var
    print var
    close(cmd)
}' file

出力

$ ./Shell.sh
01/02/2010 18:23

また、たとえばSolarisを使用している場合のように、GNUツールを使用していない場合は、nawkを使用してください。

nawk 'BEGIN{
   m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
   for(o=1;o<=m;o++){
      months[d[o]]=sprintf("%02d",o)
   }
   cmd="date +%Y"
   cmd|getline yr
   close(cmd)
}
{
    day=$3
    mth=months[$2]
    print mth"/"day"/"yr" "$4
} ' file
17
ghostdog74

Gawkを使用している場合は、外部のdateは必要ありません。これは、繰り返し呼び出すために 高価 になる可能性があります。

awk '
BEGIN{
   m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
   for(o=1;o<=m;o++){
      months[d[o]]=sprintf("%02d",o)
    }
format = "%m/%d/%Y %H:%M"
}
{
split($4,time,":")
date = (strftime("%Y") " " months[$2] " " $3 " " time[1] " " time[2] " 0")
print strftime(format, mktime(date))
}'

この回答 からの月の配列を提供してくれたghostdog74に感謝します。

Rrdfetchを使用してRRDToolデータベースから日付を変換する際にも同様の問題が発生しましたが、Apolloコンピューターの時代から使用している1つのライナーを好みます。

データは次のようになりました。

localTemp             rs1Temp             rs2Temp      thermostatMode
1547123400: 5.2788174937e+00 4.7788174937e+00 -8.7777777778e+00 2.0000000000e+00
1547123460: 5.1687014581e+00 4.7777777778e+00 -8.7777777778e+00 2.0000000000e+00

一発ギャグ:

rrdtool fetch -s -14400 thermostatDaily.rrd MAX | sed s/://g | awk '{print "echo ""\`date -r" $1,"\`" " " $2 }' | sh

結果:

Thu Jan 10 07:25:00 EST 2019 5.3373432378e+00
Thu Jan 10 07:26:00 EST 2019 5.2788174937e+00

一見すると、これは私にはあまり効率的ではありませんが、この種の方法論は、非常に低電力のコンピューター(25Mhz NeXTマシンなど)上の非常に大きなファイルの場合でも、ほとんどの状況で常にかなり低いオーバーヘッドであることが証明されています。はいMhz。

Sedはコロンを削除し、awkは、awk変数をエコーするだけで、shまたはbashが結果の文字列を実行するなど、関心のある他のさまざまなコマンドを出力するために使用されます。

方法論や大きなファイルやストリームの場合は、最初の数行を見出し、徐々に1つのライナーを作成します。コードを捨てる。

1
Ian Jefferson