2017-10-07 2 views
-1

입력 횟수별로 입력을 정렬하고 싶습니다. 그러나 고유하거나 고유하지 않은 행을 삭제하고 싶지는 않습니다. I 출력 다음과 같은 것이라고 파이프 라인 명령 세트를 찾고있을 것수를 기준으로 줄을 정렬하는 방법 UNIX?

Not unique 
This line is unique 
Not unique 
Also not unique 
Also unique 
Also not unique 
Not unique 

:

This line is unique 
Also unique 
Also not unique 
Also not unique 
Not unique 
Not unique 
Not unique 

당신이 제공 할 수있는 모든 도움을 주셔서 감사합니다 예를 들어 나는 다음과 같은 입력을 제공 한 경우 , 나는 독특하고 종류의 다른 조합을 사용하려고 시도했지만 그것을 알아낼 수 없다, 솔루션은 선호하는 한 라이너 것입니다.

업데이트 : 누구나 답변 해 주신 모든 분들께 감사드립니다. 특히 배트맨은 제가 익숙한 명령으로 찾고자했던 사람이었습니다.

나는 겉으로보기에는 간단한 작업을 위해 여러 명령을 파이프 라인하고 사용하는 방법을 배우려고 노력하고 있습니다. 따라서 2 열로 작업 할 때 그의 대답을 적용 할 수 있습니까? 예를 들어 원래의 입력이 있었다면 :

Notunique dog 
Thislineisunique cat 
Notunique parrot 
Alsonotunique monkey 
Alsounique zebra 
Alsonotunique beaver 
Notunique dragon 

그리고 난과 같이 첫 번째 열을 기준으로 정렬 할 출력을 원 :

Thislineisunique cat 
Alsounique zebra 
Alsonotunique monkey 
Alsonotunique beaver 
Notunique dog 
Notunique parrot 
Notunique dragon 

사전에 이렇게 도움을 주셔서 모두 감사합니다!

+0

당신이 보여줄 수있는 당신이 무엇을 가지고 지금까지 해봤습니까? 나는'collections.Counter'를 사용하여 매우 짧을 수있는 짧은 파이썬 스크립트를 사용 하겠지만, 이것은 순수한'shell '해결책을 위해 작동하지 않을 것이다. – norok2

답변

0

uniq + sort + grep 솔루션 :

확장 inputfile 내용 :

Not unique 
This line is unique 
Not unique 
Also not unique 
Also unique 
Also not unique 
Not unique 
Also not unique 
Also not unique 

미리 초기 파일을 정렬 :

,
sort inputfile > /tmp/sorted 

uniq -u /tmp/sorted; uniq -dc /tmp/sorted | sort -n | cut -d' ' -f8- \ 
    | while read -r l; do grep -x "$l" /tmp/sorted; done 

출력 :

Also unique 
This line is unique 
Not unique 
Not unique 
Not unique 
Also not unique 
Also not unique 
Also not unique 
Also not unique 

----------

당신은 또한 bash 스크립트로 전체 작업을 묶으 수

#!/bash/bash 

sort "$1" > /tmp/sorted # $1 - the 1st argument (filename) 
uniq -u /tmp/sorted 

while read -r l; do 
    grep -x "$l" /tmp/sorted 
done < <(uniq -dc /tmp/sorted | sort -n | cut -d' ' -f8-) 
+0

이것은 출현 횟수별로 정렬하지 않고 고유 한 줄 (정렬)을 먼저 넣고 비 고유 줄은 빈도가 아니라 알파벳순으로 정렬합니다. 입력에 몇 줄 이상 '고유하지 않음'이 있으면 결과의 끝 부분에 나타나야하지만이 해결책은 아닙니다. –

+0

그냥 입력 파일로 사용하십시오. 각 문자는 별도의 줄에 있습니다 :'A A B B B C C C'. 분명한 것은 빈도로 정렬하면 'A A C C B B B B'가되거나 'B B B C C C A A'가 될 수 있지만, 변경되지 않은 입력이 될 것입니다. '유니크 (uniq) '는 입력을 재정렬하지 않고 그냥 필터링합니다. –

+0

@ BenjaminW., ok, 내 업데이트를 확인하십시오. – RomanPerekhrest

0

나는 각 행이 발생 횟수를 계산하는 awk을 사용하고이를 출력 (사전 보류 주파수에 의해) 및 종류 수치 sort -n를 사용하여 :

awk 'FNR==NR{freq[$0]++; next} {print freq[$0],$0}' data.txt data.txt | sort -n 

샘플 출력

1 Also unique 
1 This line is unique 
2 Also not unique 
2 Also not unique 
3 Not unique 
3 Not unique 
3 Not unique 

Schwartzian 변형입니다.선행 빈도 열을 버리려면 명령 끝에 | cut -d ' ' -f 2-을 붙이기 만하면됩니다.

1

awk 만 업데이트 된 질문에 가장 적합합니다.

$ awk '{file[$0]++; count[$1]++; max_count= count[$1]>max_count?count[$1]:max_count;} END{ k=1; for(n=1; n<=max_count; n++){ for(i in count) if(count[i]==n) ordered[k++]=i} for(j in ordered) for(line in file) if (line~ordered[j]) print line; }' file 

Alsounique zebra 
Thislineisunique cat 
Alsonotunique beaver 
Alsonotunique monkey 
Notunique parrot 
Notunique dog 
Notunique dragon 

설명 :

파트 1 :

{file[$0]++; count[$1]++; max_count= count[$1]>max_count?count[$1]:max_count;} : 우리는 file 배열에 입력 파일을 저장하는

; count 배열은 파일을 정렬 할 기준으로 각 고유 한 첫 번째 필드의 수를 추적합니다. max_count은 최대 개수를 추적합니다.

파트 2 : AWK는 파일을 읽는 완료되면, count의 내용은 다음과 같다 : (키, 값)

Alsounique 1 
Notunique 3 
Thislineisunique 1 
Alsonotunique 2 

지금 우리의 목표 값으로이 키를 정렬하는 것입니다 같이 이하. 아래의 각 필드/키/열 1에 대한 우리의 핵심 단계는 file 배열을 반복하고 이러한 키가 포함 된 줄을 인쇄하면 최종 원하는 출력이 제공됩니다. 루프 아래

Alsounique 
Thislineisunique 
Alsonotunique 
Notunique 

다른 배열 count 어레이의 콘텐츠를 저장하는 동작은 sorted by valuesordered 방식이라고한다. ordered의 내용은 위에 표시된 출력과 같습니다.

for(n=1; n<=max_count; n++) 
    { 
     for(i in count) 
      if(count[i]==n) 
      ordered[k++]=i 
    } 

최종 단계 : 즉file 반복 배열 및 ordered 어레이에 저장 필드의 순서로 선을 인쇄한다.

for(field in ordered) 
    for(line in file) 
     if (line~ordered[field]) 
      print line; 
    } 

해결책-2 : 다른 해결 방안이 종류, UNIQAWK를 사용하는 것입니다
/
를 잘라. 그러나 여러 파이프가 여러 프로세스를 호출하여 전체 작업 속도를 늦추므로 입력 파일이 매우 큰 경우이 방법을 사용하지 않는 것이 좋습니다.

$ cut -d ' ' -f1 file | sort | uniq -c | sort -n | awk 'FNR==NR{ordered[i++]=$2; next} {file[$0]++;} END{for(j in ordered) for(line in file) if (line~ordered[j]) print line;} ' - file 
Alsounique zebra 
Thislineisunique cat 
Alsonotunique beaver 
Alsonotunique monkey 
Notunique parrot 
Notunique dog 
Notunique dragon 

이전 솔루션 (OP 편집하기 전에 문제)이이 같은 sort, uniqawk을 사용하여 수행 할 수

:

$ uniq -c <(sort f1) | sort -n | awk '{ for (i=1; i<$1; i++){print}}1' 
     1 Also unique 
     1 This line is unique 
     2 Also not unique 
     2 Also not unique 
     3 Not unique 
     3 Not unique 
     3 Not unique 
+0

정말 고마워요. 내가 찾던 것을 정확히 수행합니다! 나는 파이프 라인을 만들고 겉으로보기에 간단한 작업을 위해 여러 명령을 사용하는 방법을 배우려고 노력 중이므로이 기능을 2 열로 작동하도록 조정할 수 있습니까? 예를 들어 너무 Thislineisunique 2 같이 첫 번째 열에 의해 정렬 될 일본어 입력 3 Alsonotunique 4 Alsounique 5 Alsonotunique 6 고유하지 7 Notunique 1 Thislineisunique 2 Notunique 을되었고 I 출력을 원한다면 Alsounique 5 Alsonotunique 4 Alsonotunique 6 Notunique 이전 댓글이 내가 그래서 숫자는 그냥 원래의 게시물을 편집 텍스트 – trysofter

+0

을 나타내는 1 Notunique 3 Notunique 7 n 더 나은 형식, 다시 한번 감사드립니다! – trysofter

+0

첫 번째 열은 접근 방식이 중복됩니다 – RomanPerekhrest

관련 문제