각각 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
를 최종 파이프로 사용할 수 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