열의 텍스트 구문 분석

열의 텍스트 구문 분석
2018-05-24 23:57:30 1.1.1.1 8.8.4.4
2018-05-24 23:57:32 2.2.2.2 8.8.4.4
2018-05-24 23:58:12 8.8.8.8 8.8.4.4
2018-05-24 23:58:23 8.8.8.8 8.8.4.4
2018-05-24 23:59:40 8.8.8.8 8.8.4.4
2018-05-24 23:59:51 8.8.8.8 8.8.4.4

위 형식의 로그 파일이 있기 때문입니다. 이제 이를 구문 분석해야 하며 출력은 아래와 같아야 합니다. (행 데이터가 중복되면 세 번째와 네 번째 열을 비교하여 첫 번째와 마지막 행만 표시됩니다.

2018-05-24 23:57:30 1.1.1.1 8.8.4.4
2018-05-24 23:57:32 2.2.2.2 8.8.4.4
2018-05-24 23:58:12 8.8.8.8 8.8.4.4
2018-05-24 23:59:51 8.8.8.8 8.8.4.4

답변1

Perl이 구조에 옵니다:

perl -ane '
    if ($F[2] ne $c3 || $F[3] ne $c4) {
        $printed or print $previous;
        $printed = print;
    } else {
        $printed = 0;
    }
    ($c3, $c4, $previous) = (@F[2, 3], $_);
    END { print $previous unless $printed }
' -- input.file
  • -n입력된 내용을 한 줄씩 읽고 각 줄에 대한 코드를 실행합니다.
  • -a각 입력 줄을 공백의 @F 배열로 분할합니다.
  • $c3과 $c4는 3열과 4열의 이전 값을 보관하는 데 사용되며, 실제 값은 $F[2]와 $F[3](0부터 시작하는 인덱스 배열)에 저장됩니다.
  • $previous는 인쇄해야 할 경우를 대비해 이전 줄을 저장합니다.
  • $printed는 마지막 줄이 두 번 인쇄되는 것을 방지합니다(3번째와 4번째 열이 이전 줄과 다를 경우 발생).

답변2

그리고 awk:

awk '!first[$3, $4]{ first[$3, $4]= $0 } { last[$3, $4]= $0 }
    END{ for (x in last) print first[x] (last[x] != first[x]? ORS last[x]:"") }' infile
2018-05-24 23:58:12 8.8.8.8 8.8.4.4
2018-05-24 23:59:51 8.8.8.8 8.8.4.4
2018-05-24 23:57:30 1.1.1.1 8.8.4.4
2018-05-24 23:57:32 2.2.2.2 8.8.4.4

연관 first배열은 열#3과 열#4의 키 조합을 사용하여 처음 발생하는 행을 유지하지만 배열은 last매번 동일한 키를 사용하여 최신 행을 유지합니다.

모든 행을 읽은 후 first배열의 값은 처음 나타나는 행(고유한 열 #3, #4 포함)이고, last배열의 값은 마지막에 나타나는 행입니다.

이는 3열과 4열의 중복 조합이 없는 END유일한 first행인 경우 행의 중복을 방지하는 데 사용됩니다 .last(last[x] != first[x]? ORS last[x]:"")

답변3

이 경우 유일한 행을 사용하여 열 3,4를 비교한 다음 마지막 행을 추가할 수도 있습니다. 그러나 다른 모든 행에 서로 다른 세 번째 및 네 번째 열이 있는 경우 이로 인해 마지막 행이 중복될 수 있습니다.

그런 다음 uniq에 다른 파이프를 추가하고 필요에 따라 제거하십시오.

{uniq <your_file> -f2; tail -n1 <your_file>; } | cat | uniq

-f는 여기에서 공백으로 구분된 처음 2개의 필드를 건너뜁니다.

답변4

첫 번째 변종

paste -d'\n' <(uniq -f2 input.txt) <(tac input.txt | uniq -f2 | tac) | uniq

두 번째 변형

awk '
$3$4 == prev {
    buf = $0 ORS
}
$3$4 != prev {
    print buf $0
    prev = $3$4
    buf = ""
}
END {
    printf("%s", buf)
}' input.txt

시험

입력(테스트하기 복잡함)

2018-05-24 23:57:30 1.1.1.1 8.8.4.4
2018-05-24 23:57:32 2.2.2.2 8.8.4.4
2018-05-24 23:58:12 8.8.8.8 8.8.4.4
2018-05-24 23:58:23 8.8.8.8 8.8.4.4
2018-05-24 23:59:40 8.8.8.8 8.8.4.4
2018-05-24 23:59:51 8.8.8.8 8.8.4.4
2018-05-25 00:18:12 8.8.1.8 8.8.4.4
2018-05-25 00:18:23 8.8.1.8 8.8.4.4
2018-05-25 00:19:40 8.8.1.8 8.8.4.4
2018-05-25 00:19:51 8.8.1.8 8.8.4.4
2018-05-25 00:39:51 8.8.2.8 8.8.4.4
2018-05-25 00:49:52 8.8.2.8 8.8.4.4
2018-05-25 00:59:51 8.8.2.8 8.8.4.4

출력(두 가지 변형)

2018-05-24 23:57:30 1.1.1.1 8.8.4.4
2018-05-24 23:57:32 2.2.2.2 8.8.4.4
2018-05-24 23:58:12 8.8.8.8 8.8.4.4
2018-05-24 23:59:51 8.8.8.8 8.8.4.4
2018-05-25 00:18:12 8.8.1.8 8.8.4.4
2018-05-25 00:19:51 8.8.1.8 8.8.4.4
2018-05-25 00:39:51 8.8.2.8 8.8.4.4
2018-05-25 00:59:51 8.8.2.8 8.8.4.4

관련 정보