サブシェル初期化変数を持つawk

サブシェル初期化変数を持つawk

なぜこれがうまくいかないのですか?

$ echo "1" | awk '{ d=$(echo hi); print d }'

$ echo "1" | awk '{ print $(echo hi) }'

$ echo "1" | awk '{ d=$(date); print d }'

すべて「hi」/現在の日付の代わりに「1」を印刷します。

何が問題なの?

awkの外で実行すると正常に動作します。

$ d=$(echo hi); echo $d; -> prints "hi"

私の究極の目標は、次のことができることです。

$ cat dates | awk ' { d=$(date --date=$1 +"%s"); print d } '

日付のリストを見たいです。

2021-12-26T22:24:08+00:00
2021-12-26T22:24:18+00:00
2021-12-26T22:26:12+00:00
2021-12-26T22:28:07+00:00

そして、各日時のUnixタイムスタンプを表示します。

ベストアンサー1

GNUを使用すると、date次のように日付を含むファイルを直接読み取ることができます-f

$ cat file
2021-12-26T22:24:08+00:00
2021-12-26T22:24:18+00:00
2021-12-26T22:26:12+00:00
2021-12-26T22:28:07+00:00
$ date -f file +%s
1640557448
1640557458
1640557572
1640557687
$ date -f file +%s%t%c
1640557448      Sun Dec 26 23:24:08 2021
1640557458      Sun Dec 26 23:24:18 2021
1640557572      Sun Dec 26 23:26:12 2021
1640557687      Sun Dec 26 23:28:07 2021

awk は独自のプログラミング言語なので、awkプログラムでシェル拡張を使用することはできません。$(...)inの設定は、awkシェルで行われているものとはかなり異なることを行います(アクセスするフィールドの数は角括弧内の式の結果であり、$(1+2)これはinと同じです$3。これはシェルの3番目のフィールド値です)。現在の記録)。

お持ちの場合本物これを行うには、入力ファイルの各行で各日付の一部を選択してから、その文字列を使用してUnixタイムスタンプを作成awkできます。この機能は非標準ですが、一般的な実装でサポートされています(マニュアルを参照)。substr()mktime()mktime()awkawk

以下は、入力から読み取られたタイムスタンプをUTCタイムゾーンとして解釈します。

BEGIN { FS = "[-T+:]" }

{
        ts = mktime(sprintf("%.4d %.2d %.2d %.2d %.2d %.2d",
                $1, $2, $3, $4, $5, $6))

        off = -60*(60*$7 + $8)
}

/-..:..$/ { off = -off }

{ print ts + off }

substr()時間をコレクションの文字に分割するので、ここではそれを使用する必要はありません。-T+:したがって、タイムスタンプの他の部分にフィールドとして直接アクセスできます。

$ TZ=UTC awk -f script file
1640553848
1640553858
1640553972
1640554087

おすすめ記事