행의 연속된 숫자를 기준으로 .CSV 파일 필터링

행의 연속된 숫자를 기준으로 .CSV 파일 필터링

다음과 같은 CSV 파일이 있습니다.

                 1st       2nd      3rd       4th
   ID      ...   Res       Res      Res       Res        (other columns) ...

RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper
RZ_AUTO_4, 1ffk, C2767, 0, C2682, 0, G2679, 0, A2681, 0, CC/GA Naked ribose-zipper
RZ_AUTO_5, 1ffk, G2574, 0, C2575, 0, G2798, 0, A2776, 0, GC/GA Single ribose-zipper

내가 하고 싶은 것은 행(First_Residue(세 번째 필드)과 Second_Residue($5)의 숫자가 연속됨)와 (Third_Residue($7)과 Fourth_Residue($9)의 숫자가 연속됨)을 추출하는 것입니다. 예제 출력은 다음과 같습니다.

RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper

4행과 5행은 나머지 숫자가 연속되지 않기 때문에 삭제됩니다.

awk나 sed를 사용하여 이 작업을 어떻게 수행할 수 있나요?

답변1

비교하려는 각 필드에 숫자가 아닌 접두사 문자( 예에서는 CA)가 있는 경우 awk에서 직접 숫자 하위 문자열을 추출하고 비교할 수 있어야 합니다.

$ awk -F"[ \t,]+" 'substr($5,2)+0==substr($3,2)+1 && substr($9,2)+0==substr($7,2)+1' file.csv
RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper 
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper 
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper

답변2

사용할 수 있는 경우 perl:

$ perl -F, -anle '
    map { s/\D//g } @F;
    print if ++$F[2] == $F[4] and ++$F[6] == $F[8];
' file
RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper

답변3

이 Bash 스크립트는 원하는 작업을 수행하지만 단지 sedand 를 사용하는 것만은 아닙니다 awk. 개발에 더 많은 시간을 투자하면 더 개선될 수 있다고 확신하지만 대략적으로 원하는 대로 작동합니다.

$ more cmd.bash 
#!/bin/bash

while read line; do 
    f1=$(echo "$line" | awk -F", " '{print $3}')
    f2=$(echo "$line" | awk -F", " '{print $7}')
    echo "$line" | grep  "${f1}.*$(expr ${f1:2} + 1).*${f2}.*$(expr ${f2:2} + 1)"
done <file

예제 실행

$ ./cmd.bash 
RZ_AUTO_1, 1cx0, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_2, 1drz, C118, B, C119, B, A165, B, A166, B, CC/AA Canonical ribose-zipper
RZ_AUTO_3, 1ffk, C208, 0, G209, 0, A665, 0, A666, 0, CG/AA Canonical ribose-zipper

약점

더욱 강화가 필요한 부분 중 하나는 경기 선정이다 grep. 이는 현재 양식에서 오탐지로 이어질 수 있습니다. .와 같은 도구를 사용하거나 선을 일치시키는 데 사용되는 패턴을 강화하면 awk더 잘 수행할 수 있습니다 .grep

관련 정보