awkを使用して絶対値を取得する方法は?


14

2つ以下の日付がある場合:

2015-09-12,2015-08-13

そして、それらの間の日数を取得する必要があります。以下のコードを使用します。

awk -F'[-,]' '{print 360*($4-$1)+30*($5-$2)+($6-$3)}'

このコードの出力は-29、実際の違いは29

回答:



11

この種の状況の一般的なトリックは、平方の平方根を使用することです:

awk -F'[-,]' '{print sqrt((360*($4-$1)+30*($5-$2)+($6-$3))^2)}'

3
ちょっとやり過ぎ。これsqrt(x^2)は問題ありませんsqrt(x)^2が、小さなエラーが発生する可能性があります。busyboxのawk場合、数学サポートを有効にしてビルドする必要があります(たとえば、Debianパッケージのデフォルトではありません)。
ステファンシャゼラス

3
sqrt(x)^ 2は単に負の数に対して失敗しませんか?
ダニエルマクラウリー

1
@DanielMcLauryそれが理由ですsqrt(x^2)
jimmij

@jimmij:回答そのものではなく、回答のコメントに返信しています。
ダニエルマクラウリー

3

別の方法:

awk -F'[-,]' '{d=360*($4-$1)+30*($5-$2)+($6-$3);print (d>0)?d:-d}'

これがおそらく最も効率的な(パフォーマンス)答えです。
ハスター

2

GNUを使用していると仮定するとawkmktimeここでファンキーな機能が役立ちます。

awk -F, '{ gsub(/-/," ",$0);a=(mktime($2 " 23 59 59")-mktime($1 " 00 00 00"))/86400;print a*(a<0?-1:1)}' file.txt
29

1

遅刻しますが、ここにGNU dateコマンドを使用したソリューションがあります。これは、上記のすべての回答がスティーブの回答と見なした毎月30日の固定に基づいていません。

awk -F, '{cmd="printf \"%d\n\" $((($(date -d"$1" +%s)-$(date -d"$2" +%s))/86400))"; 
    cmd|getline $0; $0*=($0<0?-1:1); close(cmd)}1' infile

以下の入力の場合:

2015-09-12,2015-08-13
2017-02-12,2017-03-12

出力は次のとおりです。

30
28
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.