다음과 같은 파일이 있습니다.
chr1 3000823 3000829 1
chr1 3001003 3001009 1
chr1 3001014 3001020 1
chr1 3001273 3001279 2
chr1 3001625 3001631 3
chr1 3003222 3003228 4
chr1 3003335 3003341 4
chr1 3003375 3003381 4
chr1 3003578 3003584 4
chr1 3003636 3003642 4
chr1 3003717 3003723 4
chr1 3003881 3003887 4
chr1 3003894 3003900 4
chr1 3004526 3004532 5
chr1 3005994 3006000 6
chr1 3006183 3006189 6
chr1 3006412 3006418 7
chr1 3006778 3006784 8
chr1 3006877 3006883 8
chr1 3007166 3007172 9
chr1 3007426 3007432 10
chr1 3007528 3007534 10
chr1 3007576 3007582 10
네 번째 열에 특정 숫자가 포함된 행을 특정 횟수만큼 가져오고 싶습니다.
4열에 같은 숫자가 3배 있는 행을 가져오고 싶다고 가정하면 출력은 다음과 같습니다.
chr1 3000823 3000829 1
chr1 3001003 3001009 1
chr1 3001014 3001020 1
chr1 3007426 3007432 10
chr1 3007528 3007534 10
chr1 3007576 3007582 10
..이 행의 숫자 1과 10이 4열에 3번 나타나기 때문입니다.
어떤 아이디어라도 크게 감사하겠습니다. 감사해요!
답변1
해결책 awk
:
awk 'FNR==NR{c[$4]++;next;} c[$4]==3' file.dat file.dat
산출:
chr1 3000823 3000829 1
chr1 3001003 3001009 1
chr1 3001014 3001020 1
chr1 3007426 3007432 10
chr1 3007528 3007534 10
chr1 3007576 3007582 10
설명하다:
FNR==NR
: 이 테스트는 레코드 수가 파일의 레코드 수와 같을 때 참입니다. 두 번째 파일NR
은 file1 + FNR의 줄 수와 같기 때문에 이것은 첫 번째 파일에서만 작동합니다 .c[$4]++
: 배열 요소 인덱스를 증가시킵니다$4
. 카운터로 사용하고 있어요.next
: 다른 작업을 수행하지 않고 다음 레코드로 이동합니다.c[$4]==3
: 이는 두 번째 파일의 레코드에만 발생합니다. 이 테스트가 성공하면 인쇄가 이므로 해당 행이 인쇄됩니다awk
.
이 코드의 단점은 파일을 두 번 읽는다는 것입니다. 그러나 제 생각에는 이것이 작업을 수행하는 깔끔하고 이해하기 쉬운 방법입니다.
답변2
{
i = int(count[$4])
arr[$4,i] = $0
count[$4]++
}
END {
for (i in count) {
if (count[i]== n) {
for (j=0; j<n; j++) {
printf("%s\n", arr[i,j])
}
}
}
}
sample run --
awk -v n=3 -f 1.awk 1.dat
chr1 3007426 3007432 10
chr1 3007528 3007534 10
chr1 3007576 3007582 10
chr1 3000823 3000829 1
chr1 3001003 3001009 1
chr1 3001014 3001020 1
awk -v n=8 -f 1.awk 1.dat
chr1 3003222 3003228 4
chr1 3003335 3003341 4
chr1 3003375 3003381 4
chr1 3003578 3003584 4
chr1 3003636 3003642 4
chr1 3003717 3003723 4
chr1 3003881 3003887 4