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
로드 하려고 하면 누군가가 해당 디렉터리에 악성 코드를 심었을 수 있습니다. 시스템과 함께 제공되는 확장 프로그램 의 경로 는 다를 수 있습니다. 출력을 참조하세요.inplace
inplace
inplace.awk
inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
-F,
-v OFS=,
입력 및 출력 필드 구분 기호를 설정합니다 .mktime()
형식의 문자열을 구문 분석year month day hour minute second
하고 해당 Unix 시대 시간을 반환하는 GNU awk 확장입니다. 여기서는 (또 다른 gawk 확장)을 사용하여 네 번째 필드( ) 를 공백으로 대체gensub()
하여 시간을 전달합니다 .-
YYYY-MM-DD
YYYY MM DD 0 0 0
mktime()
(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
패키지는 miller
Ubuntu 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
로 읽고 숫자를 계산한 다음 문자열로 변환합니다. 그런 다음 해시에서 요일을 조회하여 알파벳순 날짜를 제공합니다.Date
day-of-week
Str
%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