각 파일에는 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 변수이며 현재 레코드의 필드 수로 자동 설정됩니다. $i
i번째 필드를 참조하여 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
a를 최종으로 파이프하면 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