bashでx日の追加をvarに変換する方法

bashでx日の追加をvarに変換する方法

次のような行が多いファイルがあります。

0 D FakeSip          192.169.192.192                      jan/26/2022 17:10:31

IPアドレスと日付をエクスポートしてから、日付に10日を追加して有効期限を指定したいと思います。 IPを取得して日付を挿入することは問題ありませんが、日付に10日を追加してエクスポートするのは痛いです。少しでも助けてくれてありがとう。

cat FakeSip.txt|awk --posix '$4 ~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ { print " IP Address "$4 " Date Identified "$5 " Expiration " (date -d  $5+10 days);}' 

これは上記の出力です。

IP Address 192.241.212.118 Date Identified jan/25/2022 Expiration 010

希望の出力は次のとおりです。

IP Address 192.169.192.192 Date Identified jan/26/2022 Expiration Feb/05/2022

答え1

  LANG=C LC_ALL=C awk '
    $4 ~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/
      {
        dvar = $5;
        gsub("[^[:digit:][:alpha:]]+"," ",dvar); # turn any special character into space to make date parseable and protect against command injection
        cmd = "date -d \"" d"+10 days\" +%b/%d/%Y";
        cmd | getline expire; close(cmd);
        print " IP Address "$4 " Date Identified "$5 " Expiration " expire
      }
    ' FakeSip.txt

クレジットのためこの回答、コマンド出力を変数に割り当てるためのコードをコピーしました。

答え2

そしてzsh

#! /bin/zsh -
zmodload zsh/datetime
read -r x y z ip date time < FakeSip.txt &&
  LC_ALL=C strftime -rs t     '%b/%d/%Y %H:%M:%S' "$date $time" &&
  LC_ALL=C strftime  -s expire %b/%d/%Y           $((t+10*24*60*60)) &&
  print -r IP Address $ip Date Identified $date Expiration $expire

これはLC_ALL=C、これらの月の略語を英語に解釈/出力することを強制することです。ユーザーの言語で解釈/出力されるように削除します。

日付は現地時間として解釈され、864000秒を加算します。定義方法によって常に10日になるわけではありません。そして夏時間が関係している場合。

$expire小文字に変換する月の名前をそのスタイルと一致するのではなく${(L)expire}(または同様のもの)に変更します。$expire:ltcshLfebFebjan

答え3

パーティーに遅れましたが、デートの質問が好きです。

パールを使って

use strict;
use warnings;
use Time::Piece;

# regex stolen from Regexp::Common::net
# https://metacpan.org/pod/Regexp::Common::net

my $re_ipv4 = qr/(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))/o;
my $fmt = '%b/%d/%Y';

while (<>) {
    my @F = split ' ';
    if ($F[3] =~ /^$re_ipv4$/) {
        my $dt = Time::Piece->strptime($F[4], $fmt);
        my $exp = ($dt + 86400 * 10)->strftime($fmt);
        print "IP Address $F[3] Date Identified $F[4] Expiration " . lc($exp) . "\n";
    }
}

私は仕事を表示するために秒を追加することはあまり好きではありませんが、このコードはタイムゾーンをサポートしていないため、夏時間の変換は機能しません。これを「正しく」実行するには、次のものが必要です。DateTimeそしてDateTime::Format::StrptimeCPANのモジュール。

これにより

$ perl add10.pl file
IP Address 192.169.192.192 Date Identified jan/26/2022 Expiration feb/05/2022

またはルビー、

require 'date'

re_ipv4 = Regexp.new("^(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))$")
fmt = '%b/%d/%Y'

File.new(ARGV.shift).each do |line|
  fields = line.split
  if fields[3].match?(re_ipv4)
    dt = Date.strptime(fields[4], fmt)
    exp = (dt + 10).strftime(fmt).downcase
    puts "IP Address #{fields[3]} Date Identified #{fields[4]} Expiration #{exp}"
  end
end

そして

$ ruby add10.rb file
IP Address 192.169.192.192 Date Identified jan/26/2022 Expiration feb/05/2022

関連情報