awk를 사용하여 동일한 수의 열 식별

awk를 사용하여 동일한 수의 열 식별

각각 6개의 열이 포함된 개별 파일이 많이 있습니다(행 수는 다를 수 있음). 간단한 예를 들면 다음과 같습니다.

1   0   0   0   0   0

0   1   1   1   0   0

나는 얼마나 많은 고유한 열(즉, 숫자와 순서가 일치하는지)을 식별하려고 합니다. 이 경우에는 3이 됩니다.

이 작업을 수행하는 간단한 단일 라이너가 있습니까? 한 열을 다른 열과 비교하는 것이 쉽다는 것을 알고 있지만 동일한 열을 찾는 방법은 무엇입니까?

답변1

다음 파이프를 사용하여 고유 열을 계산할 수 있습니다.

$ awk '{for (i=1; i<=NF; ++i) a[i]=a[i]$i; } END { for (i in a) print a[i] }' foo \
  | sort -u | wc -l

awk 명령은 입력 내용을 바꾸고, 결과 줄을 정렬하고, 고유한 줄만 유지하고( -u), 마지막에는 모든 (고유한) 줄(즉, 전치된 열)을 계산합니다( wc -l).

이는 NF내장 awk 변수이며 현재 레코드의 필드 수로 자동 설정됩니다. $ii번째 필드를 참조하고 END모든 레코드가 처리된 후 실행되도록 다음 블록을 보호합니다. Awk는 기본적으로 공백-공백이 아닌 필드 구분을 사용합니다.

답변2

(((...))), 그러나 동일한 열을 찾는 방법은 무엇입니까?

$ printf '%s\n' '1 0 0 0 0 0' '0 1 1 1 0 0' | awk -vSUBSEP='=' '
    { for (i=1; i<NF; i++)
        for (j=i+1; j<=NF; j++)
          if ($i==$j)
            M[i,j]++
    }
    END{ for (m in M) if (M[m]==NR) print m }'
5=6
2=3
2=4
3=4

i<j각 행의 모든 ​​열에 대해 M[i,j]해당 열의 값이 동일할 때마다 증가합니다. 따라서 행을 M[i,j]==NR읽은 후에는 NR읽은 모든 행에 대해 값이 동일했습니다.

답변3

이 질문은 저를 흥미롭게 만들었고 제가 정확히 알 수 없는 접근 방식을 따르고 싶었지만 훌륭한 도움을 받았습니다.다른 질문으로 게시한 후. 내가 게시한 질문을 통해 따르려는 접근 방식을 이해할 수 있습니다.

이 문제에 대한 해결책이 2개 더 있습니다(하나는그누크의대답은솔루션과 또 다른 존스내 솔루션과 결합된 솔루션).

#The variable appended_input will remove spaces/tabs and just append the rows. 
#Modify the file name in this line. Here I use inputfile as the filename. 

appended_input=$(column -s '\t' inputfile | tr -d '[:space:]') ;

#The array variable will store each column-wise value as an array element.  
#I use sort to find the number of unique elements.

array=($(
    for ((i=0; i<6; i++))
    do
        new=${appended_input:$i:1}
        for ((j=i+6; j<${#appended_input}; j=j+6))
        do 
            new="$new${appended_input:$j:1}"
        done
        echo "$new"
    done
    )) | echo "${array[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '

테스트

내 입력 파일은 다음과 같습니다.

1 0 0 1 0 0
0 1 1 0 0 0
1 1 1 1 1 0
1 0 0 1 0 1
1 0 0 1 0 1

위의 스크립트를 실행한 후 다음과 같은 결과를 얻습니다.

00011 00100 01100 10111

를 최종 파이프로 사용할 수 wc -w있으며 위와 같이 고유한 열 값 대신 4로 출력을 얻을 수 있습니다.

답변4

다음은 gawk코프로세스를 사용하여 각 열을 별도의 인스턴스에 제공 sha256sum하고 총 고유 해시 수를 보고하는 솔루션입니다. 고유 해시 수는 해시 충돌 가능성이 통계적으로 중요하지 않다는 점을 고려하여 고유 열 수와 일치해야 합니다 sha256sum. 어떤 사람들은 이것을 심각한 해킹이라고 생각할 수도 있지만, 이 접근 방식이 다른 접근 방식에 비해 갖는 한 가지 장점은 데이터를 연결/전치를 시도하지 않으므로 상대적으로 메모리 효율적이라는 것입니다.

awk 'BEGIN{for(i=1; i<=6; ++i){s=sprintf("%*s", i+1, ""); a[i]="sha256sum"s}}
    {for (i=1; i<=6; ++i) print $i |& a[i]}
    END{com= "sort | uniq | wc -l"
    for (i=1; i<=6; ++i){close(a[i], "to"); a[i] |& getline x;
    close(a[i]); print x | com};
    close(com)}' file 

관련 정보