파일에서 고유하지 않은 모든 줄 찾기

파일에서 고유하지 않은 모든 줄 찾기

파일에서 고유하지 않은 모든 줄을 찾으려면 uniq를 사용하려고 합니다. 고유하지 않다는 것은 이전 행에서 이미 본 모든 행을 의미합니다. 내 생각에 "-D" 옵션은 다음과 같은 역할을 합니다.

-D     print all duplicate lines

그러나 반복되는 줄을 인쇄하는 대신모두여러 줄이 있을 때. 행의 두 번째 및 후속 사본만 인쇄하고 싶습니다.

어떻게 해야 하나요?

답변1

소문자 -d 옵션의 GNU 버전이 필요합니다.

# printf "a\na\na\nb\nb\nc\n" | uniq -d
a
b

답변2

GNU 또는 ast-open을 사용하여 구현됨 uniq:

uniq -D -u < input

( -D자체는 비표준), 그러나 이것은 첫 번째가 아니라 제거하는 마지막 중복이라는 점에 유의하십시오( -i, 또는 도 사용하면 -w차이가 발생함 -f).

이식 가능한 경우 언제든지 다음을 사용할 수 있습니다 awk.

awk 'NR > 1 && $0 "" == previous ""; {previous = $0}' < input

(is와 연결하면 ""피연산자가 숫자처럼 보이더라도 문자열 비교가 강제됩니다.)

처음 9자만 비교합니다(이것은 -w또한 GNU 확장이며 (현재) 문자가 아닌 바이트에서 작동한다는 점에 유의하십시오(문서에 그렇게 나와 있지만)).

awk '{current = substr($0, 1, 9)}
     NR > 1 && current == previous
     {previous = current}' < input

""(이 경우 substr()문자열이 반환되므로 연결이 필요하지 않습니다.)

UTF-8 로케일에서 출력 시

printf '%s\n' StéphaneChazelas StéphaneUNIX StéphaneUnix

StéphaneUnix예상대로 while uniq -w9 -D -u(GNU 사용 uniq) 을 제공 StéphaneChazelas하고 -is StéphaneUNIX로 8자를 제공 Stéphane하지만 UTF-8에서는 9바이트를 제공하는 반면 ast-open uniq은 StéphaneUNIX( awk첫 번째 항목 건너뛰기, uniq마지막 항목 한 번 제거)만 제공합니다.

를 사용하면 awk다음 항목에 인접하지 않더라도 모든 중복 행을 보고할 수도 있습니다.

 awk 'seen[$0]++' < input

(메모리의 모든 고유 행을 해시 테이블에 저장합니다.)

또는 처음 9자만 고려하십시오.

 awk 'seen[substr($0, 1, 9)]++' < input

답변3

해결책은 uniq를 사용한 -c 다음 원하는 것을 제거하는 것 입니다.

e444$ (   echo a ; echo a ; echo b ; echo d ; echo d ; echo e )  | uniq -c
  2 a
  1 b
  2 d
  1 e 

a 반복 d 되어 이중 b으로e

e444$ (   echo a ; echo a ; echo b ; echo d ; echo d ; echo e )  | uniq -c  \             
              | sed -E '/^ *1 .$/d;s/^ *[0-9]+ //'

표현 설명 sed :

/^ *1 .$/d모든 고유 행을 삭제합니다

s/^ *[0-9]+ // 카운터가 삭제됩니다

관련 정보