unix 명령을 사용하여 각 줄의 고유 값을 얻으십시오.

unix 명령을 사용하여 각 줄의 고유 값을 얻으십시오.

다음과 같은 목록이 있습니다.

1 2 5 2
1 5 5 3
1 5 5 5
5 2 2 2
2 2 4 3

각 행을 정렬하고 다음과 같은 고유한 값을 얻고 싶습니다 sort | uniq.

1 2 5
1 3 5
1 5
2 5
2 3 4

온라인에서 솔루션을 찾고 있지만 열별로 정렬하는 솔루션만 찾을 수 있습니다. 어떻게 출력을 얻을 수 있나요? 미리 감사드립니다.

답변1

행 내의 열보다 행을 정렬하는 것이 더 쉽기 때문에 한 가지 접근 방식은 각 행을 전치하여(각 필드가 행이 되도록) 적용한 sort다음 uniq전치하는 것입니다.

다음은 GNU 도구를 가정한 간단한 구현입니다.

$ while read -r line; do echo "$line" | grep -o '[^ ]*' | sort -h | uniq | paste -s; done <file

file각 행에 대해 루프를 통해 다음을 수행합니다.

  • grep-o옵션(각 줄의 일치하는 부분만 인쇄)을 사용하여 입력을 다음으로 분할합니다.N일치하는 각 하위 문자열에 대해 하나씩. 여기서는 공백을 제외한 모든 항목을 일치시킵니다.
  • 분할선은 -h사람이 읽을 수 있는 숫자를 비교하는 옵션을 사용하여 정렬됩니다(필드를 영숫자 문자열로 정렬하려면 이 옵션을 제거하세요 -h).
  • uniq명령은 중복된 항목을 제거합니다.
  • paste -s표준 입력의 각 행을 탭으로 구분된 단일 행 필드로 인쇄합니다. 후행 | tr '\t' ' '문자를 추가하여 탭을 공백으로 변경할 수 있습니다.

그러나 루프를 사용하여 텍스트를 처리하는 것은 일반적으로나쁜 습관으로 간주.

답변2

다음은 여러 열에 걸쳐 데이터를 정렬하지 않고 고유한 값만 추출합니다. 정렬이 필요한지 여부는 불분명합니다.

사용 awk:

$ awk '{ n=split($0,a,FS); $0=""; j=1; delete u; for (i=1; i<=n; i++) if (!u[a[i]]++) $(j++) = a[i]; print }' <file
1 2 5
1 5 3
1 5
5 2
2 4 3

이 프로그램은 주석과 함께 훌륭하게 구성되어 있습니다.

{
    # split the current record into fields in the array a
    n = split($0, a, FS)

    # empty the current record
    $0=""

    # j is the next field number that we are to set
    # in the record that we are building
    j=1

    # seen is an associative array that we use to
    # keep track of whether we've seen a bit of
    # data before from this record
    delete seen

    # loop over the entries in a (the original
    # fields of the input data)
    for (i=1; i<=n; i++)
        # if we haven't seen this data before,
        # mark it as seen and...
        if (!seen[a[i]]++)
            # add it to the j:th field in the new record
            $(j++) = a[i]

    print
}

여기서 내 생각은 원본 데이터의 고유한 필드를 포함하는 각 입력 행에 대한 출력 레코드를 작성하는 것입니다.

기본적으로 "record"는 "row"와 동의어이고 "field"는 "column"과 동의어입니다(이것은 및 의 현재 값에 따라 더 일반적인 단어일 뿐입니다 RS) FS.

답변3

펄 사용:

perl -MList::Util=uniq -alne 'print join " ", sort { $a <=> $b } uniq @F' file
1 2 5
1 3 5
1 5
2 5
2 3 4

답변4

bash@fra-san의 접근 방식과 유사한 또 다른 접근 방식입니다.

while read X;do tr<<<$X ' ' \\n|sort -u|paste -sd" ";done<file
1 2 5
1 3 5
1 5
2 5
2 3 4

관련 정보