줄 끝에 요일을 추가하는 방법을 찾고 있습니다.

줄 끝에 요일을 추가하는 방법을 찾고 있습니다.

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현재 작업 디렉터리(as or)에서 확장 기능을 먼저 gawk로드 하려고 하면 누군가가 해당 디렉터리에 악성 코드를 심었을 수 있습니다. 시스템과 함께 제공되는 확장 프로그램 의 경로 는 다를 수 있습니다. 출력을 참조하세요.inplaceinplaceinplace.awkinplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'
  • -F,-v OFS=,입력 및 출력 필드 구분 기호를 설정합니다 .
  • mktime()형식의 문자열을 구문 분석 year month day hour minute second하고 해당 Unix 시대 시간을 반환하는 GNU awk 확장입니다. 여기서는 (또 다른 gawk 확장)을 사용하여 네 번째 필드( ) 를 공백으로 대체 gensub()하여 시간을 전달합니다 .-YYYY-MM-DDYYYY MM DD 0 0 0mktime()
  • (t = mktime(...)) > 0 {...}각 입력 레코드에서 두 쌍이 실행 1됩니다 ( 여기서는condition {action}철사).
    • 첫 번째의 경우,상황mktime()t반환된 값이 0보다 큰지(날짜 지정을 구문 분석할 수 없는 경우 반환됨 mktime()) 확인(할당)합니다.-1행동달리기. strftime()(또 다른 gawk 확장자) C와 마찬가지로 시간 형식을 지정하는 데 사용됩니다(Unix 시대 시간은 여기에 현지화된 요일 이름 t형식으로 저장됩니다). %A결과를 첫 번째 NF필드( $NF)에 할당합니다. NF이 필드는 현재 레코드의 필드 수를 포함하는 특수 변수이자 $필드 내용(또는 로 전체 레코드)을 검색하는 $ 0연산자 입니다.

    • 두 번째 ( 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
      

사용자의 로케일에 관계없이 요일 이름을 항상 영어로 표시하려면 로케일을 C( LC_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.04 universe저장소에서 사용할 수 있습니다.

답변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줄 헤더의 경우 을 사용합니다 put (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

관련 정보