중복된 항목을 제거하고 뒤에 특정 단어가 있는 항목만 유지합니다.

중복된 항목을 제거하고 뒤에 특정 단어가 있는 항목만 유지합니다.

저는 bash 스크립팅을 처음 접했고 현재 스크립트에 약간의 코드를 변경하고 싶습니다.

다음과 비슷하게 날짜와 날짜 뒤에 "활성" 또는 "비활성"이라는 단어가 포함된 파일이 있습니다.

2019-02-17 not active
2019-02-18 active
2019-02-19 not active
2019-02-19 not active
2019-02-19 active
2019-02-19 not active
2019-02-19 not active
2019-02-19 active
2019-02-20 active
2019-02-21 not active
2019-02-22 not active

"2019-02-19 활성"의 복사본을 유지하면서 "2019-02-19 비활성"의 모든 중복을 제거하고 싶습니다. 귀하의 의견에 진심으로 감사드립니다. 감사해요!

답변1

GNU를 사용하면 uniq다음을 수행할 수 있습니다.

 sort file | uniq -w 10

옵션은 -w비교를 10자로 제한하므로 각 날짜는 한 번만 유지됩니다. 정렬하면 active첫 번째 항목이 나타나므로 뒤에 남게 됩니다.

예를 들어, 이 질문의 미래 독자가 GNU가 없는 시스템을 사용하게 된다면 를 uniq사용할 수 있습니다. sed중복 행을 제거하는 일반적인 방법은 다음과 같습니다.

sed '$!N;/^\(.*\)\n\1$/!P;D'

N;P;D패턴은 패턴 공간에 항상 두 줄을 유지하지만, 두 번째 줄이 다를 경우 첫 번째 줄만 인쇄됩니다. 날짜 부분의 중복 항목만 확인하도록 이 스크립트를 변경할 수 있습니다.

sed '$!N;/^\([^ ]*\) .*\n\1/!P;D'

active이제 다음 줄을 선택하도록 주의하면 됩니다 .

sed '$!N;/^\([^ ]*\) .*\n\1/!P;//s/\(.*\)\(\n\).*not.*/\2\1/;D'

첫 번째 부분은 동일하게 유지됩니다. 날짜가 변경된 이후의 행(또는 마지막 행)만 인쇄합니다. 그러나 날짜가 동일한 경우(주소의 빈 패턴은 //이전 패턴의 반복을 의미함) 일반적으로 두 번째 행이 유지됩니다. 그러나 두 번째 줄 not이 포함된 경우 첫 번째 줄( active또는 )을 유지하는 것이 더 좋으 not active므로 이 s명령은 첫 번째 줄을 두 번째 줄로 만듭니다(어쨌든 제거될 빈 줄 다음 D).

나는 이것이 GNU 버전보다 덜 우아하다는 것을 인정하지만 적어도 여전히 농담입니다.

답변2

고유한 정렬이 이를 수행할 수 있습니다.

$ sort -u input.txt
2019-02-17 not active
2019-02-18 active
2019-02-19 active
2019-02-19 not active
2019-02-20 active
2019-02-21 not active
2019-02-22 not active

그런데, sort input.txt | uniq동일한 작업을 수행하며 고유성을 결정할 때 필드를 건너뛰는 옵션 과 고유한 행 대신 고유하지 않은 행을 인쇄하려는 경우의 옵션 도 uniq있습니다 .-f-d-D


또는 날짜당 하나의 출력 행만 원하는 경우 "활성" 항목이 "비활성"(또는 기타) 항목보다 우선합니다.

perl -lane '
  $date=shift @F;
  $day{$date} = join(" ",@F) unless ($day{$date} eq "active");
  END {print $_ . " " . $day{$_} for (sort keys %day)}' input.txt
2019-02-17 not active
2019-02-18 active
2019-02-19 active
2019-02-20 active
2019-02-21 not active
2019-02-22 not active

%day날짜를 키로 하고 나머지 필드를 값으로 사용하여 해시( )를 작성합니다 . 특정 날짜에 대해 현재 또는 마지막으로 표시된 값이 이전에 표시된 값을 대체합니다.~하지 않는 한특정 날짜의 값은 이미 "활성" 상태입니다. 이 경우 오늘의 값은 대체되지 않습니다.

모든 입력을 읽은 후 %day 해시가 정렬되어 인쇄됩니다.

이는 두 번째 필드의 정렬 순서에 의존하는 것보다 일반적으로 더 유용하고 재사용이 가능합니다. 예를 들어 "zzzzz"가 "action"보다 우선하도록 하려는 경우입니다. 두 번째 필드에 "작업" 이전에 정렬된 항목(예: 숫자)이 포함될 수 있는 경우에도 유용합니다.

관련 정보