파일에서 중복 행을 찾고 각 행이 복제 된 횟수를 계산합니까?


529

다음과 비슷한 파일이 있다고 가정하십시오.

123 
123 
234 
234 
123 
345

'123'이 여러 번 복제되었는지, '234'가 여러 번 복제되었는지 등을 찾고 싶습니다. 이상적으로 출력은 다음과 같습니다.

123  3 
234  2 
345  1

4
어떤 언어를 사용 하시겠습니까?
VMAtm

답변:


791

한 줄에 하나의 숫자가 있다고 가정합니다.

sort <file> | uniq -c

--count예를 들어 Linux에서 GNU 버전과 함께 더 자세한 플래그를 사용할 수도 있습니다 .

sort <file> | uniq --count

3
이것이 내가 알고리즘 적으로하는 일이지만 이것이 가장 효율적인 접근법은 아닙니다 (O (n log n) * avg_line_len 여기서 n은 줄 수입니다). 몇 기가 바이트 크기의 파일을 작업 중이므로 성능이 중요한 문제입니다. 접두사 트리 (내 경우에는 문자열에 공통 접두사가있는 경우)를 사용하여 단일 패스로 계산하는 도구가 있는지 또는 O (n) * avg_line_len의 트릭을 수행 해야하는 도구가 있는지 궁금합니다. 누구나 그런 명령 줄 도구를 알고 있습니까?
Droggl

21
추가 단계는 출력을 최종 'sort -n'명령으로 파이프하는 것입니다. 그러면 선이 가장 자주 나타나는 결과가 정렬됩니다.
samoz

79
당신은 단지, 중복 라인을 인쇄 사용하려면 'UNIQ -d'
DmitrySandalov

6
결과를 다시 정렬하려면 다음 sort과 같이 다시 사용할 수 있습니다 .sort <file> | uniq -c | sort -n
Abhishek Kashyap

413

이것은 것이다 중복 라인만을 인쇄 건의를 :

sort FILE | uniq -cd

또는 GNU 긴 옵션 (Linux의 경우) :

sort FILE | uniq --count --repeated

BSD와 OSX 당신은 그렙 사용해야하는 독특한 라인 필터링 :

sort FILE | uniq -c | grep -v '^ *1 '

주어진 예에서 결과는 다음과 같습니다.

  3 123
  2 234

한 번만 나타나는 줄을 포함하여 모든 줄의 개수인쇄 하려면 다음을 수행하십시오.

sort FILE | uniq -c

또는 GNU 긴 옵션 (Linux의 경우) :

sort FILE | uniq --count

주어진 입력에 대한 출력은 다음과 같습니다.

  3 123
  2 234
  1 345

가장 빈번한 줄로 출력정렬하려면 다음을 수행하여 모든 결과를 얻을 수 있습니다.

sort FILE | uniq -c | sort -nr

또는 중복 행만 얻으려면 가장 자주 시작하십시오.

sort FILE | uniq -cd | sort -nr

OSX와 BSD에서 마지막 것은 다음과 같습니다.

sort FILE | uniq -c | grep -v '^ *1 ' | sort -nr

1
--repeated 또는 -d 옵션을 사용하는 것이 좋습니다. "| grep 2"또는 이와 유사한 것을 사용하는 것보다 훨씬 더 정확합니다!
Lauri

반복 횟수가 100보다 많은 모든 행을 검색하도록이 명령을 수정하는 방법은 무엇입니까?
Black_Rider

@Black_Rider 파이프에 | sort -n또는 | sort -nr파이프에 추가하면 반복 횟수 (오름차순 또는 내림차순)별로 출력이 정렬됩니다. 이것은 당신이 요구하는 것이 아니지만 도움이 될 것이라고 생각했습니다.
Andrea

1
@Black_Rider awk는 모든 종류의 계산을 수행 할 수있는 것 같습니다 : 귀하의 경우 할 수있는| awk '$1>100'
Andrea

4
@fionbio OSX uniq에서 -c와 -d를 함께 사용할 수없는 것 같습니다 . 지적 해 주셔서 감사합니다. grep을 사용하여 고유 한 줄을 걸러 낼 수 있습니다 .sort FILE | uniq -c | grep -v '^ *1 '
Andrea

72

여러 파일에서 중복 행을 찾아서 계산하려면 다음 명령을 시도하십시오.

sort <files> | uniq -c | sort -nr

또는:

cat <files> | sort | uniq -c | sort -nr

30

통하다 :

awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data

에서 awk 'dups[$1]++'명령 변수는 $1컬럼 1의 전체 내용을 보유하고 대괄호 배열 액세스한다. 따라서 data파일 의 첫 번째 행 열마다 이름 dups이 지정된 배열의 노드 가 증가합니다.

마지막 으로 변수로 dups배열을 반복 num하고 저장된 숫자를 먼저 인쇄 한 다음 중복 값의 수를로 인쇄합니다 dups[num].

입력 파일에는 일부 줄의 끝에 공백이 있습니다.이를 지우면 $0위의 $1명령 대신 사용할 수 있습니다 . :)


1
우리가 가지고 있다고 생각하면 약간의 과잉이 uniq아닙니까?
Nathan Fellman

9
sort | uniqawk 솔루션은 성능과 리소스 균형이 상당히 다릅니다. 파일이 크고 다른 줄 수가 적 으면 awk 솔루션이 훨씬 더 효율적입니다. 라인 수는 선형이며 공간 사용량은 다른 라인 수는 선형입니다. OTOH, awk 솔루션은 모든 다른 줄을 메모리에 보관해야하며 (GNU) 정렬은 임시 파일에 의존 할 수 있습니다.
Lars Noschinski

14

"Windows PowerShell" 을 사용하는 Windows에서는 아래에서 언급 한 명령을 사용하여이 작업을 수행했습니다.

Get-Content .\file.txt | Group-Object | Select Name, Count

또한 where-object Cmdlet을 사용하여 결과를 필터링 할 수 있습니다

Get-Content .\file.txt | Group-Object | Where-Object { $_.Count -gt 1 } | Select Name, Count

파일의 정렬 순서를 변경하지 않고 마지막 항목을 제외한 모든 중복 항목을 삭제할 수 있습니까?
jparram

6

표준 Unix 쉘 및 / 또는 cygwin 환경에 액세스 할 수 있다고 가정합니다.

tr -s ' ' '\n' < yourfile | sort | uniq -d -c
       ^--space char

기본적으로 : 모든 공백 문자를 줄 바꿈으로 변환 한 다음 변환 된 출력을 정렬하여 uniq에 공급하고 중복 줄을 계산하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.