타임스탬프의 첫 번째 행을 아래 목록에 추가하세요.

타임스탬프의 첫 번째 행을 아래 목록에 추가하세요.

다음과 같은 입력을 얻으십시오.

08/22/2019 12:00:58
Name Cans Bucks Puns
Clyde 12 2 79
Sheila 32 16 42
Elmo 44 18 21

08/23/2019 19:00:22
Name Cans Bucks Puns
Clyde 18 21 46
Sheila 37 2 11
Elmo 41 3 10

다음과 같이 출력됩니다.

name=Clyde cans=12 bucks=2 puns=79 ts=1566475258
name=Sheila cans=32 bucks=16 puns=42 ts=1566475258
name=Elmo cans=44 bucks=18 puns=21 ts=1566475258
name=Clyde cans=18 bucks=21 puns=46 ts=1566586822
name=Sheila cans=37 bucks=2 puns=11 ts=1566586822
name=Elmo cans=41 bucks=3 puns=10 ts=1566586822

나는 awk를 사용하여 이를 달성하려고 시도했지만 성공하지 못했습니다(완전히 당황한 시간 변환 제외).

내가 얻은 가장 가까운 것은 다음과 같습니다.

ts=08/22/2019 12:00:58
name=Clyde cans=12 bucks=2 puns=79
name=Sheila cans=32 bucks=16 puns=42
name=Elmo cans=44 bucks=18 puns=21
ts=08/23/2019 19:00:22
name=Clyde cans=18 bucks=21 puns=46
name=Sheila cans=37 bucks=2 puns=11
name=Elmo cans=41 bucks=3 puns=10

awk가 최고의 도구인지조차 확신할 수 없습니다.

답변1

awk -F'[/: ]' '{
  if (NF==6){
    ts=mktime($3" "$1" "$2" "$4" "$5" "$6)
    skipheader=1
  }
  else if (NF==0 || skipheader){
    skipheader=0
  }
  else {
    print "name="$1,"cans="$2,"bucks="$3,"puns="$4,"ts="ts
  }
}' file
  • /:별도의 날짜 및 시간 부분을 얻으려면 , 및 공백 문자를 사용하여 필드를 분할하십시오 .
  • 필드 수가 6개인 경우 타임스탬프를 만들고 ts다음 헤더 행을 건너뛰도록 플래그를 설정합니다.
  • 필드 수가 0이거나 skipheader플래그가 설정된 경우 skipheader플래그를 재설정합니다.
  • 그렇지 않으면 데이터를 인쇄하십시오.

산출:

name=Clyde cans=12 bucks=2 puns=79 ts=1566468058
name=Sheila cans=32 bucks=16 puns=42 ts=1566468058
name=Elmo cans=44 bucks=18 puns=21 ts=1566468058
name=Clyde cans=18 bucks=21 puns=46 ts=1566579622
name=Sheila cans=37 bucks=2 puns=11 ts=1566579622
name=Elmo cans=41 bucks=3 puns=10 ts=1566579622

답변2

다음 Perl 스크립트는 입력의 필드 수와 필드 이름에 관계없이 작동합니다.

소요된다시간::날짜그리고목록::추가 유틸리티라이브러리 모듈. 이 두 가지는 배포용으로 이미 패키지되어 있을 수 있습니다(예: debian sudo apt-get install libtimedate-perl liblist-moreutils-perl). 이러한 모듈이 필요하지 않도록 스크립트를 작성하는 것이 가능하지만 기존 재사용 가능한 라이브러리 코드가 필요한 작업을 정확하게 수행할 때 바퀴를 다시 만들 필요는 없습니다.

스크립트는 입력 줄이 공백 수(예: 하나 이상의 공백, 탭 등)로 구분되어 있다고 가정합니다. 입력이 탭으로 구분된 경우 줄을 split;로 변경합니다 split /\t/;. 첫 번째 필드의 이름에 공백이 포함되어 있거나(예: ) 필드 이름에 공백이 포함된 경우 Firstname Surname탭 구분 기호를 사용하는 것이 좋습니다 .

예를 들어 특정 시간대를 하드코딩해야 하는 경우 GMT다음 줄을 변경합니다.

    $ts = str2time($_);

예를 들어(앞의 따옴표 안의 공백에 유의하세요 GMT):

    $ts = str2time($_ . ' GMT');
#!/usr/bin/perl

use strict;
use Date::Parse;
use List::MoreUtils qw(pairwise);

my @columns;
my $ts='';

while(<>) {
  s/^\s*|\s*$//g;    #/ strip leading and trailing spaces
  next if (/^$/);    #/ skip empty lines
  chomp;

  # line begins with two digits and a slash? it's a date.
  if (m/^\d\d\//) {
    # get the date and parse it so that we have seconds since the epoch
    $ts = str2time($_);

    # get the next line and split it into column headers
    $_ = readline;
    @columns = split;

  } else {
    # split the current line into @row array
    my @row=split;
    # use pairwise() function from List::MoreUtils module to merge the
    # @columns and @row arrays.
    print join(" ", (pairwise { "$a=$b" } @columns, @row), "ts=$ts"), "\n";
  }

}

예제 출력:

$ ./reformat.pl input.txt 
Name=Clyde Cans=12 Bucks=2 Puns=79 ts=1566439258
Name=Sheila Cans=32 Bucks=16 Puns=42 ts=1566439258
Name=Elmo Cans=44 Bucks=18 Puns=21 ts=1566439258
Name=Clyde Cans=18 Bucks=21 Puns=46 ts=1566550822
Name=Sheila Cans=37 Bucks=2 Puns=11 ts=1566550822
Name=Elmo Cans=41 Bucks=3 Puns=10 ts=1566550822

참고: 데이터 행에 열 머리글 수보다 많거나 적은 열이 있는 경우 완전히 중단되지는 않지만 비정상적인 출력이 생성됩니다. 누락된 필드의 경우 부호는 있지만 값은 없는 필드 이름만 인쇄합니다 =(예: 입력 줄에 필드가 2개만 있는 경우 출력). 필드가 더 많은 경우 접두사가 Puns=붙은 값만 인쇄합니다( =예를 들어 , 입력 라인에 값이 20인 추가 필드가 있으면 출력됩니다 =20.

예를 들어, 예시 입력에 다음과 같은 세 번째 데이터 블록이 있는 경우:

08/23/2019 23:30:01
Name Cans Bucks Puns
Clyde 18 21 46
Sheila 37 2 11
Elmo 41 3 10
Missing 41 3
Extra 41 3 10 20

그러면 추가 출력이 발생합니다.

Name=Clyde Cans=18 Bucks=21 Puns=46 ts=1566567001
Name=Sheila Cans=37 Bucks=2 Puns=11 ts=1566567001
Name=Elmo Cans=41 Bucks=3 Puns=10 ts=1566567001
Name=Missing Cans=41 Bucks=3 Puns= ts=1566567001
Name=Extra Cans=41 Bucks=3 Puns=10 =20 ts=1566567001

관련 정보