7番目のフィールドがyyyymmddhhmmssのこのファイルがあります。この数字を1秒ずつ増やす必要があります。
これまで私は見つけました:
awk 'BEGIN{FS=OFS="|"} $7=$7+1 ' <file>
うまくいくようですが... 7番目のフィールドの最後の2桁の数字が「59」の場合は、明らかに「60」に置き換えられます。
列全体を1秒ずつ増やすためにフィールドが日付であることをawkに通知する方法はありますか?
現在のファイル
09099458|1|000|41181|0|0|20221130164738|67
82060649|1|000|36827|0|0|20221130172359|67
予想される結果
09099458|1|000|41181|0|0|20221130164739|67
82060649|1|000|36827|0|0|20221130172400|67 <- From 17:23:59 to 17:24:00
よろしくお願いします。
ベストアンサー1
GNUを使用awk
する@トーマスディキmawk
1:
$ gawk -F'|' -v OFS='|' '{
gsub("..", "& ", $7)
sub(" ", "", $7)
$7 = strftime("%Y%m%d%H%M%S", mktime($7) + 1)
print}' < your-file
09099458|1|000|41181|0|0|20221130164739|67
82060649|1|000|36827|0|0|20221130172400|67
呼び出しは、目的の形式を取得するために最初のスペースを削除しますgsub()
。後者はこれをUNIX時代に変換します。 1を追加し、YYYYmmddHHMMSSにフォーマットを変更します。"20221130164739"
"20 22 11 30 16 47 39 "
sub()
"2022 11 30 16 47 39 "
mktime()
awk
サポートしていない場合は、/mktime()
いつでもコアモジュールをstrftime()
使用できます。perl
Time::Piece
perl -MTime::Piece -F'\|' -lase '
$F[6] = (Time::Piece->strptime($F[6], $format) + 1) -> strftime($format);
print join "|", @F' -- -format=%Y%m%d%H%M%S < your-file
ここでは、入力文字列を日付として解析するために、標準のC関数と同じ名前の関数を使用しますTime::Piece
。strptime()
これにより、ソリューションを他の日付形式に簡単に適応させることができます(移動性が向上します)。
両方がないgawk
場合、一部のシェル(zshやksh93など)には、日付/時刻の解析と書式設定機能が組み込まれています。mawk
perl
たとえば、zsh
次のようになります。
zmodload zsh/datetime
format=%Y%m%d%H%M%S
while IFS='|' read -ru3 -A fields; do
strftime -rs t $format $fields[7] &&
strftime -s 'fields[7]' $format $(( t + 1 ))
print -r -- ${(j[|])fields}
done 3< your-file
1以降バージョン 20121129この記事を書いた時点で、リリースはほぼ正確に10年前でした。