行末に曜日を追加する方法を探しています。

行末に曜日を追加する方法を探しています。

Ubuntu 16.04では、テキストファイルの各行の末尾に曜日を追加する方法を見つけようとしています(フィールド4に日付が指定されています)。

サンプル:

Server ID,Make,"Server Room",Datestamp,Timestamp,Distance,Ping,Download,Upload,Payload,"Src IP Address",Hour,DOW
x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,4, 
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,10, 
x6883551,Dell,"Server Room A",2019-08-16,02:00:04,26.444,17.921,86551957,88775986,,192.168.1.1,2, 
s1555023,HP,"Server Room C",2018-02-06,04:50:01,516.574,402.527,907658,608152,,192.168.1.1,4, 
s3398023,HP,"Server Room B",2019-01-17,10:50:01,56.574,40.233,48484827,45620028,,192.168.1.1,10, 
s1555098,IBM,"Server Room C",2018-11-18,02:00:03,516.514,404.671,819027,601233,,192.168.1.1,2, 
x6883582,Dell,"Server Room A",2019-05-19,04:50:02,26.444,12.506,88871436,84360552,,192.168.1.1,4,

たとえば、データライン#1と#2の場合:

x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,4,Sunday
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,10,Saturday

様々なSEDとAWKを試してみましたが、何の役にも立ちません。 DATEコマンドを試しましたが、入力が気に入らないようです。実際の日付と比較してみました。

grep -w -o "20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]*"

しかし、私はそれを変換し、行の最後にDOWを追加するのを見ませんでした。

各データ行の最後に曜日を追加できるようにするために私が見逃しているのは何ですか?また、CRONTAB 操作でこの操作を実行できる必要があります。

答え1

GNUを使用すると、awk次のことができます。

gawk -i /usr/share/awk/inplace.awk -F, -v OFS=, -v date_field=4 '
  (t = mktime(gensub("-", " ", "g", $date_field) " 0 0 0")) > 0 {
    $NF = strftime("%A", t)};1' your-file
  • -i /usr/share/awk/inplace.awk: gawk の内部編集モードを有効にして、入力ファイルを置き換える新しいファイルに出力を書き込みます。使用しないでください-i inplace現在の作業ディレクトリから最初に拡張機能をgawkロードしようとすると、誰かがそのディレクトリにマルウェアを植えた可能性があります。システムに付属の拡張プログラムのパスは異なる場合があります。出力を参照してください。inplaceinplaceinplace.awkinplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'
  • -F,-v OFS=,入力および出力フィールドの区切り記号を設定します。
  • mktime()型の文字列を解析し、対応するyear month day hour minute secondUnix時代を返すGNU awk拡張。ここでは、(別のgawk拡張)を使用して4番目のフィールド()を空白に置き換えてgensub()時間を渡します。-YYYY-MM-DDYYYY MM DD 0 0 0mktime()
  • (t = mktime(...)) > 0 {...}各入力レコードで2つのペアが実行され1ます(ここではcondition {action}ワイヤー)。
    • 最初のケースでは、状況mktime()t返された値が0より大きいか(日付指定を解析できない場合は返されますmktime())、確認(割り当て)します。-1行動ランニング。strftime()(別のgawk拡張子)Cと同様に、時間形式を指定するために使用されます(Unix時代の時間は、ここでローカライズされた曜日名t形式で保存されます)。%A結果を最初のNFフィールド($NF)に割り当てます。NFこのフィールドは、現在のレコード内のフィールド数を含む特殊変数であり、フィールドの$内容(または全体レコード)を取得する$ 0演算子です。

    • 2番目(1)がありません。行動{print}デフォルトは(現在のレコードを印刷)で、状況1)は常に真です。これは、現在のレコードを条件なしで印刷する慣用的な短い方法です。詳しく知りたい場合は、次のようにできます。

          gawk -i /usr/share/awk/inplace.awk \
               -v FS=, \
               -v OFS=, \
               -v date_field=4 \
               -v current_record=0 \
               -v always=1 '
            {
              date_for_mktime = gensub("-", " ", "g", $date_field) " 0 0 0"
              unix_time = mktime(date_for_mktime)
            } 
            unix_time > 0 {
              $NF = strftime("%A", unix_time)
            }
            always {print $current_record}' your-file
      

ユーザーのロケールに関係なく、曜日名を常に英語で表示するには、ロケールをCLC_ALL=C gawk...)で固定します。

答え2

そしてミラー( mlr):

mlr --csvlite put '
  $Hour = ""; $DOW = strftime(strptime($Datestamp,"%Y-%m-%d"),"%A")
' file.csv

前任者。

$ mlr --csvlite put '$Hour = ""; $DOW = strftime(strptime($Datestamp,"%Y-%m-%d"),"%A")' file.csv
Server ID,Make,"Server Room",Datestamp,Timestamp,Distance,Ping,Download,Upload,Payload,"Src IP Address",Hour,DOW
x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,,Sunday
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,,Saturday
x6883551,Dell,"Server Room A",2019-08-16,02:00:04,26.444,17.921,86551957,88775986,,192.168.1.1,,Friday
s1555023,HP,"Server Room C",2018-02-06,04:50:01,516.574,402.527,907658,608152,,192.168.1.1,,Tuesday
s3398023,HP,"Server Room B",2019-01-17,10:50:01,56.574,40.233,48484827,45620028,,192.168.1.1,,Thursday
s1555098,IBM,"Server Room C",2018-11-18,02:00:03,516.514,404.671,819027,601233,,192.168.1.1,,Sunday
x6883582,Dell,"Server Room A",2019-05-19,04:50:02,26.444,12.506,88871436,84360552,,192.168.1.1,,Sunday

パッケージはmillerUbuntu 16.04universeリポジトリで利用できます。

答え3

私の最初の反応はスティーブンの反応と同じでした。

Perlも動作します:

perl -MTime::Piece -F, -lape '
  if ($F[3] =~ /^[\d-]+$/) {
    $F[-1] = Time::Piece->strptime($F[3], "%Y-%m-%d")->strftime("%A");
    $_ = join ",", @F;
  }
' file

答え4

使用幸せ(以前のPerl_6)

~$ raku -ne 'BEGIN my %days  = ( 1 => "Monday", 2 => "Tuesday", 3 => "Wednesday", 4 => "Thursday", 5 => "Friday", 6 => "Saturday", 7 => "Sunday" ) andthen put get;  
             put $_, %days{.split(",")[3].Date.day-of-week.Str};'  file

または:

~$ raku -ne 'BEGIN my %days  = ( 1 => "Monday", 2 => "Tuesday", 3 => "Wednesday", 4 => "Thursday", 5 => "Friday", 6 => "Saturday", 7 => "Sunday" );  
             $++ == 0 ?? .put !! put $_, %days{.split(",")[3].Date.day-of-week.Str};'  file

上記の答えは、Raku(Perlプログラミング言語シリーズ)でコード化された答えです。どちらの例も、-ne自動印刷ライン固有のフラグを使用します。

最初の例では、%daysハッシュ値がブロックで宣言されていますBEGIN。ヘッダー行を印刷するにはput get(2行ヘッダーの場合を使用します。2put (get xx 2)番目の例では、Rakuの三項演算子を使用してヘッダーを印刷します。$++ == 0??(True)!!(False)。2行ヘッダーの場合を使用します$++ < 2

どちらの例もトピック変数を印刷し、曜日を計算$_するコードを印刷します。コンマで区切られたコードは、0インデックス== 3(列4)を取得し、オブジェクトとして読み取り、数値を計算.split(",")[3].Date.day-of-week.Strして文字列に変換します。その後、ハッシュで曜日を照会し、アルファベット順の日付を提供します。Dateday-of-weekStr%days{ … }

入力例:

Server ID,Make,"Server Room",Datestamp,Timestamp,Distance,Ping,Download,Upload,Payload,"Src IP Address",Hour,DOW
x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,4, 
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,10, 
x6883551,Dell,"Server Room A",2019-08-16,02:00:04,26.444,17.921,86551957,88775986,,192.168.1.1,2, 
s1555023,HP,"Server Room C",2018-02-06,04:50:01,516.574,402.527,907658,608152,,192.168.1.1,4, 
s3398023,HP,"Server Room B",2019-01-17,10:50:01,56.574,40.233,48484827,45620028,,192.168.1.1,10, 
s1555098,IBM,"Server Room C",2018-11-18,02:00:03,516.514,404.671,819027,601233,,192.168.1.1,2, 
x6883582,Dell,"Server Room A",2019-05-19,04:50:02,26.444,12.506,88871436,84360552,,192.168.1.1,4,

出力例:

Server ID,Make,"Server Room",Datestamp,Timestamp,Distance,Ping,Download,Upload,Payload,"Src IP Address",Hour,DOW
x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,4, Sunday
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,10, Saturday
x6883551,Dell,"Server Room A",2019-08-16,02:00:04,26.444,17.921,86551957,88775986,,192.168.1.1,2, Friday
s1555023,HP,"Server Room C",2018-02-06,04:50:01,516.574,402.527,907658,608152,,192.168.1.1,4, Tuesday
s3398023,HP,"Server Room B",2019-01-17,10:50:01,56.574,40.233,48484827,45620028,,192.168.1.1,10, Thursday
s1555098,IBM,"Server Room C",2018-11-18,02:00:03,516.514,404.671,819027,601233,,192.168.1.1,2, Sunday
x6883582,Dell,"Server Room A",2019-05-19,04:50:02,26.444,12.506,88871436,84360552,,192.168.1.1,4,Sunday

https://raku.org

関連情報